The following is a skeleton of break in scala using util.control.Breaks._ :
import util.control.Breaks._
breakable {
for (oct <- 1 to 4) {
if (...) {
} else {
break
}
}
}
This structure requires remembering several non intuitive names. I do not use break statements every other or third day - but part of that is the difficulty in remembering how to do them. In a number of other popular languages it is dead simple: break out of a loop and you're good.
Is there any mechanism closer to that simple keyword/structure in scala?
No, there isn't. for is not a loop but a syntactic sugar to a chain of functions with closures passed into them. Since the local stack changes, it cannot be translated into some goto instruction like a "normal" break does. To break the execution of arbitrarily nested closures you have to throw an exception, which is what both break and return do to exit early.
For particular situation you can often use something like .filter, .takeWhile, .dropWhile (sometimes with .sliding to look ahead), etc. For situation where you have no better idea, #tailrecursive function is always an option.
In your current example I would probably do:
(1 to 4).takeWhile(...).foreach { oct => ... }
Basically, I would consider every single case individually to write it in a declarative way.
I have a problem with pattern matching in swift switches. I need to check a string to see if it contains some characters and return data according to that.
I have the following (shortened) code:
static func getCorrectChords(chord: String) -> [Chord] {
let test = chord
switch test {
case let x where x.contains("-") && x.contains("2"):
return allChords[8]
///// other similar statements
default:
return allChords[0]
}
}
If I pass the string “RE-2” to the function, it switch over all the statements and then goes with the default case. If I try a very similar code in Playgrounds, it works correctly.
Is there anything I’m doing wrong? How can I obtain the proper return value?
Thank you very much!
Edit: corrected braces and indentation in the code. Solution is now in the answers.
I found the issue. I did not isolate the problem correctly.
The issue was that my source data had a slightly different "-" character which Swift (rightly so) did not consider equal to the condition in the switch cases. I sanitized the inputs and now it works correctly. In the playground I did manually write the input so the issue did not arise.
Thank you so much anyway!
I normally use the for in loop in swift without parentheses, but today I put them on just for kicks thinking they were just optional and it did not worked as expected.
This code works:
if let tasks = getAllTasksWithManagedObjectContext(appDelegate.managedObjectContext){
for task in tasks{
appDelegate.managedObjectContext.deleteObject(task)
}
}
This one does not:
if let tasks = getAllTasksWithManagedObjectContext(appDelegate.managedObjectContext){
for (task in tasks){
appDelegate.managedObjectContext.deleteObject(task)
}
}
I get this errors:
Whats going on here?
You are simply not allowed to use parentheses here.
Take a look at the Language Reference -> Statements and compare the C-style for-loop against the swift for-in
for-statement → for for-init;expression;expression code-block
for-statement → for (for-init;expression;expression) code-block
vs.
for-in-statement → for case(opt) pattern in expression where-clause(opt) code-block
The first one can be used with or without parentheses - your choice as the developer.
However the later one, the one you are actually asking about does not have a version with ( and ), only the one version without them. That means that it is not allowed to use them parentheses around the "argument" of the loop.
Screenshots from the docs linked above for better readability:
vs.
I have this Swift code:
for var a = 0; a < 10; a++{
println(a)
}
There is an compile error on
a++{
Can anyone explain why?
You just need to add a space between a++ and {:
for var a = 0; a < 10; a++ {
println(a)
}
If you want to use the "{" against your variable you need to use the variable name between the "+" and the "{" as per the swift documentation
for var a = 0; a < 10; ++a{
println(a)
}
Another option as suggest ABakerSmith is to space the operators "+" and "{"
I particularly prefer the first option as it keeps my code consistent as I never use space before my "{" and also it is how is used through all apple documentation
#vacawama and ABakerSmith already told you how to fix it. The reason is that Swift uses whitespace to figure out the difference between multi-character expressions and separate expressions. It requires whitespace between symbols where languages like C don't. It still trips me up sometimes.
Also, for future reference, Swift code allows for two different For loop syntaxes.
for <initialization>; <condition>; <increment> { <statements> }
or when in an array or a collection
for <identifier> in <collection> { <statements> }
But both of them require the attention to detail on where your spaces are in the code, so be careful.
Also, since it seems like you may be rather new at Swift, I recommend checking out these awesome resources that make the journey of learning Swift a lot easier.
Apple's free 500 page Swift Code Reference Guide
Thinkster.io has a great guide for everything swift, even quick little cheat sheets to keep handy for any questions you might have in the future. When I learned swift I used this site a lot!
If you want to build a cool little game using swift start here!
Hope that helped! Swift is a great programming language that has a lot to offer, and I hope you have fun learning it!
Sometimes I'm writing ugly if-else statements in C# 3.5; I'm aware of some different approaches to simplifying that with table-driven development, class hierarchy, anonimous methods and some more.
The problem is that alternatives are still less wide-spread than writing traditional ugly if-else statements because there is no convention for that.
What depth of nested if-else is normal for C# 3.5? What methods do you expect to see instead of nested if-else the first? the second?
if i have ten input parameters with 3 states in each, i should map functions to combination of each state of each parameter (really less, because not all the states are valid, but sometimes still a lot). I can express these states as a hashtable key and a handler (lambda) which will be called if key matches.
It is still mix of table-driven, data-driven dev. ideas and pattern matching.
what i'm looking for is extending for C# such approaches as this for scripting (C# 3.5 is rather like scripting)
http://blogs.msdn.com/ericlippert/archive/2004/02/24/79292.aspx
Good question. "Conditional Complexity" is a code smell. Polymorphism is your friend.
Conditional logic is innocent in its infancy, when it’s simple to understand and contained within a
few lines of code. Unfortunately, it rarely ages well. You implement several new features and
suddenly your conditional logic becomes complicated and expansive. [Joshua Kerevsky: Refactoring to Patterns]
One of the simplest things you can do to avoid nested if blocks is to learn to use Guard Clauses.
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};
The other thing I have found simplifies things pretty well, and which makes your code self-documenting, is Consolidating conditionals.
double disabilityAmount() {
if (isNotEligableForDisability()) return 0;
// compute the disability amount
Other valuable refactoring techniques associated with conditional expressions include Decompose Conditional, Replace Conditional with Visitor, Specification Pattern, and Reverse Conditional.
There are very old "formalisms" for trying to encapsulate extremely complex expressions that evaluate many possibly independent variables, for example, "decision tables" :
http://en.wikipedia.org/wiki/Decision_table
But, I'll join in the choir here to second the ideas mentioned of judicious use of the ternary operator if possible, identifying the most unlikely conditions which if met allow you to terminate the rest of the evaluation by excluding them first, and add ... the reverse of that ... trying to factor out the most probable conditions and states that can allow you to proceed without testing of the "fringe" cases.
The suggestion by Miriam (above) is fascinating, even elegant, as "conceptual art;" and I am actually going to try it out, trying to "bracket" my suspicion that it will lead to code that is harder to maintain.
My pragmatic side says there is no "one size fits all" answer here in the absence of a pretty specific code example, and complete description of the conditions and their interactions.
I'm a fan of "flag setting" : meaning anytime my application goes into some less common "mode" or "state" I set a boolean flag (which might even be static for the class) : for me that simplifies writing complex if/then else evaluations later on.
best, Bill
Simple. Take the body of the if and make a method out of it.
This works because most if statements are of the form:
if (condition):
action()
In other cases, more specifically :
if (condition1):
if (condition2):
action()
simplify to:
if (condition1 && condition2):
action()
I'm a big fan of the ternary operator which get's overlooked by a lot of people. It's great for assigning values to variables based on conditions. like this
foobarString = (foo == bar) ? "foo equals bar" : "foo does not equal bar";
Try this article for more info.
It wont solve all your problems, but it is very economical.
I know that this is not the answer you are looking for, but without context your questions is very hard to answer. The problem is that the way to refactor such a thing really depends on your code, what it is doing, and what you are trying to accomplish. If you had said that you were checking the type of an object in these conditionals we could throw out an answer like 'use polymorphism', but sometimes you actually do just need some if statements, and sometimes those statements can be refactored into something more simple. Without a code sample it is hard to say which category you are in.
I was told years ago by an instructor that 3 is a magic number. And as he applied it it-else statements he suggested that if I needed more that 3 if's then I should probably use a case statement instead.
switch (testValue)
{
case = 1:
// do something
break;
case = 2:
// do something else
break;
case = 3:
// do something more
break;
case = 4
// do what?
break;
default:
throw new Exception("I didn't do anything");
}
If you're nesting if statements more than 3 deep then you should probably take that as a sign that there is a better way. Probably like Avirdlg suggested, separating the nested if statements into 1 or more methods. If you feel you are absolutely stuck with multiple if-else statements then I would wrap all the if-else statements into a single method so it didn't ugly up other code.
If the entire purpose is to assign a different value to some variable based upon the state of various conditionals, I use a ternery operator.
If the If Else clauses are performing separate chunks of functionality. and the conditions are complex, simplify by creating temporary boolean variables to hold the true/false value of the complex boolean expressions. These variables should be suitably named to represent the business sense of what the complex expression is calculating. Then use the boolean variables in the If else synatx instead of the complex boolean expressions.
One thing I find myself doing at times is inverting the condition followed by return; several such tests in a row can help reduce nesting of if and else.
Not a C# answer, but you probably would like pattern matching. With pattern matching, you can take several inputs, and do simultaneous matches on all of them. For example (F#):
let x=
match cond1, cond2, name with
| _, _, "Bob" -> 9000 // Bob gets 9000, regardless of cond1 or 2
| false, false, _ -> 0
| true, false, _ -> 1
| false, true, _ -> 2
| true, true, "" -> 0 // Both conds but no name gets 0
| true, true, _ -> 3 // Cond1&2 give 3
You can express any combination to create a match (this just scratches the surface). However, C# doesn't support this, and I doubt it will any time soon. Meanwhile, there are some attempts to try this in C#, such as here: http://codebetter.com/blogs/matthew.podwysocki/archive/2008/09/16/functional-c-pattern-matching.aspx. Google can turn up many more; perhaps one will suit you.
try to use patterns like strategy or command
In simple cases you should be able to get around with basic functional decomposition. For more complex scenarios I used Specification Pattern with great success.