I'm writing a function that takes a request object, there are several ways that the request could be configured, but only one valid form, so before I perform my function I'd like to test how the object is configured. If I were doing this in java, I'd write something like this:
static void func(Request request) {
if (condition1)
return false
if (condition 2)
return false
if (condition 3)
return false
request.process()
return true
}
In scala though, in trying to avoid using return, I usually end up with this:
static void func(Request request) {
if (!condition1) {
if (!condition 2) {
if (!condition 3) {
request.process()
return true
}
else
return false
}
else
return false
}
else
return false
}
This is a simplified form as usually there are things that I need to do after condition 1, and then after condition 2, which mean that I can't just combine the conditions into a single if statement (e.g. condition 1 checks that something isn't null, then condition 2 checks if the value of that thing is valid).
What I'm wondering is how do I make my code clean and readable whilst still having these checks in place?
you can use pattern matching
request match {
case _ if (condition1 || condition2 || condition3) => false
case _ => request.process(); true
}
In Scala it is usual to return Option[value] rather than returning true/false and relying on side effects. And a Request object would normally be pure data, with processing done by an external function.
So a typical Scala function might look like this:
def func(req: Request): Option[Result] =
req match {
case Request(a, _, _) if condition1(a) => None
case Request(_, b, _) if condition2(b) => None
case _ =>
Some(processRequest(req))
}
You can just do a simple if else simplifying your conditions.
def func(request: Request) {
if (condition1 || condition2 || condition3)
false
else {
request.process()
true
}
}
Related
I see in scala it is a bad practice to use both while and return. I have to click on the next page link if it exists. How can I do it without while and return?
def check = {
do {
if (findElements(locator).exists(_.getText.contains(input)))
return true
} while (nextPageLocatorInPageExists(nextPageLocator))
false
}
Here's a straightforward recursive solution:
def check = {
if (findElements(locator).exists(_.getText.contains(input)))
true
else if (! nextPageLocatorInPageExists(nextPageLocator))
false
else
check
}
It can be written in a terser way by using || and &&, but then it wouldn't be tail recursive, and that's pretty much mandatory in a case like this.
From your code, I'm guessing nextPageLocatorInPageExists(nextPageLocator) mutatates locator, and that's what drives your while loop.
If that's the case, here are two options:
a do-while loop without return: the closest to what you wrote:
def check = {
var found = false
do {
found = findElements(locator).exists(_.getText.contains(input))
} while (!found && nextPageLocatorInPageExists(nextPageLocator))
found
}
a recursive solution
def check: Boolean = findElements(locator).exists(_.getText.contains(input)) ||
(nextPageLocatorInPageExists(nextPageLocator) && check)
Say you need to determine the actual associated type of an enum.
So, a situation like
enum MessageItem: Decodable {
case a(Images)
case b(Text)
case c(Reply)
...
}
I used to have code like this
xSome = x.filter {
switch $0 {
case .a(_):
return false
case .b(_):
return true
case .c(_):
return true
}
}
But then it was possible to have code like this
xSome = x.filter {
if case .a = $0 { return false }
return true
}
Is there now some way it Swift to compare against associated type producing a boolean?
So, something like:
xSome = x.filter {
return (case .a = $0)
}
So, something like anEnum.is( .someCase )
Is anything like this now in Swift?
(Naturally, I mean without adding a var in the enum, which of course you can do.)
Enums with associated values are equatable if you declare them Equatable. Here's the state of play:
enum MyEnum : Equatable {
case hey
case ho
case heyNonnyNo(String)
}
let e = MyEnum.hey
e == .hey // true
e == .ho // false
// e == .heyNonnyNo // blap, illegal
let e2 = MyEnum.heyNonnyNo("hello")
e2 == .heyNonnyNo("hello") // true
e2 == .heyNonnyNo("goodbye") // true
Why is e == .heyNonnyNo illegal? Because it's unclear what it can mean. This case has an associated value; its value is the associated value. So we can check whether two instances of this case have the same associated value, but we can't just ask (using ==) whether an instance is some associated value of this case.
So if that's what we want to know, we are back to if case:
if case .heyNonnyNo = e2 {
print("it's a hey nonny no")
}
But you can't say that without if (for use in a conditional) because if case is the keyword; case can't exist by itself. If you really need a Bool, you could write it out like this:
let ok : Bool = {
switch e2 {
case .heyNonnyNo: return true
default: return false
}
}()
What would be a good way in Scala to match an integer with Status codes defined in Akka-http:
I would like to do something like:
if (passedErrorCodeToMethod == 200) {
complete(ToResponseMarshallable(StatusCodes.OK -> errorResponse))
}
else if (passedErrorCodeToMethod == 400) {
complete(ToResponseMarshallable(StatusCodes.BadRequest -> errorResponse))
}
But I obviously don't want to do this for all error codes and would rather like to have this be done via pattern matching or in a more scalable way
StatusCodes.getForKey(passedErrorCodeToMethod) match {
case Some(status) => complete(status -> errorResponse)
case None => oopsie()
}
Something like this ?
I have this struct that has an enum property as well as a function:
struct UserInput {
enum State {
case unrestricted
case restricted(because: WarningType)
enum WarningType {
case offline
case forbidden
}
}
var config: UserInputConfig?
var state: State = .unrestricted
func isConfigured() -> Bool {
// Arbitrary checks about the config...
}
}
Is there a way to rewrite the following conditionals so that the check for isConfigured() and state are in the same statement?
if case .restricted = userInput.state {
return 1
} else if userInput.isConfigured() {
return 1
} else {
return 0
}
It seems because the State enum uses associated values, you cannot simply write if userInput.state == .restricted || userInput.isConfigured(), you need to use the if case syntax. There must be a way around this?
You would like to do this:
if case .restricted = userInput.state || userInput.isConfigured() {
return 1
} else {
return 0
}
but there is currently no way to do an OR with pattern matching. There are a couple of ways of doing AND.
By using DeMorgan's Laws, you can turn if a || b into if !(!a && !b) and by reversing the then and else clauses of your if statement, you can just check for if !a && !b.
Unfortunately, you can't say if !(case .restricted = userInput.state), but since your enum has only 2 cases, you can replace that with if case .unrestricted = userInput.state.
Now, how do you use that with another statement? You can't use && for the same reason you can't use ||.
You can check for the failing case by using a pattern that matches both failing conditions (which is using AND) and then return 1 if both failing conditions aren't met:
if case (.unrestricted, false) = (userInput.state, userInput.isConfigured()) {
return 0
} else {
return 1
}
Equivalently you can use a multi-clause condition:
if case .unrestricted = userInput.state, !userInput.isConfigured() {
return 0
} else {
return 1
}
In addition to being shorter and IMO easier to read, this second method can short circuit and skip calling userInput.isConfigured in the case where case .unrestricted = userInput.state fails.
You can do it really cleanly with a switch statement, and pattern matching:
switch userInput.state
{
case .unrestricted:
return userInput.isConfigured() ? 1 : 0;
case .restricted(_):
return 1
}
Swift 2's guide mentions that you can end program execution of an if statement. I personally have never used break with if-statement.
A break statement ends program execution of a loop, an if statement,
or a switch statement...When a break statement is followed by the
name of a statement label, it ends program execution of the loop, if
statement, or switch statement named by that label.
In what situation would one be using break in an if-statement? This language feature seems useless.
TEST:
if (true) {
break TEST
}
For example if you want to describe a number (with Strings) with reference to sets of numbers (even/rational/negative numbers) your code could look something like this:
if condition1 {
// code
if condition2 {
// code
if condition3 {
// code
if condition4 {
//code
}
}
}
}
You can achieve the same logic but without the nested ifs by refactoring it (using guard):
OuterIf: if condition1 {
// code
guard condition2 else { break OuterIf }
// code
guard condition3 else { break OuterIf }
// code
guard condition4 else { break OuterIf }
// code
}
// reads even better when breaking out of "do"
scope: do {
guard condition1 else { break scope }
// code
guard condition2 else { break scope }
// code
guard condition3 else { break scope }
// code
guard condition4 else { break scope }
// code
}
You might think that this can also be achieved with switch and fallthrough but this doesn't work with "normal" cases because it checks all conditions and if one condition is met all following conditions aren't even evaluated.
So the fallthough has to be called conditionally.
This does work but I isn't very readable not to mention its "beauty":
let x = 4
switch x {
case _ where condition1:
// code
if condition2 { fallthrough }
case _ where false:
// code
if condition3 { fallthrough }
case _ where false:
// code
if condition4 { fallthrough }
case _ where false:
// code
break
default: break
}
Using break with an if statement seems a bit contrived, and I can't think of a place where style would demand it. It does, however, save an extra level of indentation when skipping the latter portion of an if statement in an if-else clause, which can be useful for deeply nested loops.
In other languages, a popular (and/or controversial) idiom is to use labels for handling errors in deeply nested functions. For example, one might want to break out of a loop on error, like this:
func testBreak3() {
// doesn't compile!!!
let a = false, b = true, x = 10, y = 20, err = true
if !a {
if b && x > 0 {
if y < 100 {
if err {
break handleError
}
// some statements
} else {
// other stuff
}
}
}
return // avoid error handling
handleError:
print("error")
// handle the error
}
But in Swift (I'm using 2.0 as a reference), labels are different than with other languages; the above example doesn't compile for two reasons: The label isn't declared yet when it's used, and the label must be directly associated with a do, while, if, or case statement. Furthermore, break within an if or do statements requires that statement to be labeled. We can fix this as follows, although the changes make the solution less attractive due to additional tracking via the errorFlagged variable, making refactoring more attractive:
func testBreak() {
let a = false, b = true, x = 10, y = 20, err = true
var errorFlagged = false
nestedIf: if !a {
if b && x > 0 {
if y < 100 {
if err {
errorFlagged = true
break nestedIf
}
// some statements
} else {
// other stuff
}
}
}
// skip handling if no error flagged.
if errorFlagged {
print("error")
// handle error
}
}
I know this is old topic, but just now I used break and it was needed.
So my example
I have array of objects.
When user taps on a cell, i.parameter becomes True for the object in that cell.
I need to know when all the objects in the array have i.parameter = True , that's the condition to stop the game.
func forTimer(){
for i in array {
if i.parameter == false {
break
}
}
}
timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector: #selector(forTimer), userInfo: nil, repeats: true)
Even if one i.parameter = false, I do not need to check the rest of the array.
This function is called every millisecond, so I will not have to check the whole array every millisecond.