I am making a game where if a variable is equal to one number in a range of numbers an if statement will take effect. e.g. if var1 = 4, then the if will activate but it will also give an output if var1 was to equal 5, 6, 7 or 8 for example (the numbers in a set range).
I currently have no code for this part of the game so I won't be able to add it to this question.
Sorry if this question is badly explained or too vague to answer, I am new to stack overflow. Any help would be appreciated. Thank you
Probably the best way to do this is using Swift's powerful switch statements.
You can do this:
let x = 5
switch(x){
case 0..<4:
// Will match 0-3
print("one")
case 4..<10:
// will match 4-9
print("two")
case 10...:
// will match >= 10
print("three")
default:
print("other")
}
EDIT:
If that's too robust for your situation, you can also do this:
if (0..<4).contains(x){
print("yes")
}else {
print("no")
}
or even more simply:
if x >= 0 && x < 4{
print("yes")
}else {
print("no")
}
How to increment for-loop variable dynamically as per some condition.
For example.
var col = 10
for (i <- col until 10) {
if (Some condition)
i = i+2; // Reassignment to val, compile error
println(i)
}
How it is possible in scala.
Lots of low level languages allow you to do that via the C like for loop but that's not what a for loop is really meant for. In most languages, a for loop is used when you know in advance (when the loop starts) how many iterations you will need. Otherwise, a while loop is used.
You should use a while loop for that in scala.
var i = 0
while(i<10) {
if (Some condition)
i = i+2
println(i)
i+=1
}
If you dont want to use mutable variables you can try functional way for this
def loop(start: Int) {
if (some condition) {
loop(start + 2)
} else {
loop(start - 1) // whatever you want to do.
}
}
And as normal recursion function you'll need some condition to break the flow, I just wanted to give an idea of what can be done.
Hope this helps!!!
Ideally, you wouldn't use var for this. fold works pretty well with immutable values, whether it is an int, list, map...
It lets you set a default value (e.g. 0) to the variable you want to return and also iterate through the values(e.g i) changing that value (e.g accumulator) on every iteration.
val value = (1 to 10).fold(0)((loopVariable,i) => {
if(i == condition)
loopVariable+1
else
loopVariable
})
println(value)
Example
I want to write a binary search program in Scala without using any if-else statements at all. Basic strategy which i have devised uses the return value of comparison between array[mid] and search_key. In short :
1) Generate return value based on comparison between array[mid] and search_key
2) Create a unique string using that return value.
3) Call function using 'reflection' with help of that string
So my question is ...is there any computational logic which returns different values in this case ? How can i achieve this ? For example :
if array[mid] == search_key , return 0
if array[mid] > search_key , return 1
if array[mid] < search_key , return 2
If anyone have any better solution for this problem, please also suggest that.
The easy way that does something similar is
array(mid) compareTo search_key
This line is equivalent to
if (array(mid) == search_key) 0
else if (array(mid) < search_key) -1
else 1 // if (array(mid) > search_key)
As for the best way to do it, you could make a sequence of actions to take, and compute an index into that sequence. If you are interested you can see the full code in https://gist.github.com/kolmar/bcfc94ee4051ee7eb3a1
Hello guys I'm new here and right now I'm learning Swift by coding some fancy algorithms, which comes to my mind while reading Apples Swift book.
I was trying to compress (automatically downcast) any IntegerType value.
Here is a little snippet of my Code which almost works fine except for one case:
switch signedValue
{
case Int64(Int8.min)...Int64(Int8.max): compressedValue = Int8(signedValue)
case (Int64(Int8.max) + 1)...Int64(UInt8.max): compressedValue = UInt8(signedValue)
case Int64(Int16.min)...Int64(Int16.max): compressedValue = Int16(signedValue)
case (Int64(Int16.max) + 1)...Int64(UInt16.max): compressedValue = UInt16(signedValue)
case Int64(Int32.min)...Int64(Int32.max): compressedValue = Int32(signedValue)
case (Int64(Int32.max) + 1)...Int64(UInt32.max): compressedValue = UInt32(signedValue)
case Int64(Int.min)...Int64(Int.max): compressedValue = Int(signedValue) // range bug #1 - workaround '..<'
default: compressedValue = signedValue
}
Assume signedValue is of Type Int64 and the input value is = 10_000_000_000.
This will lead to a runtime error (in Playground):
Execution was interrupted, reason: EXC_BAD_INSTRUCTION ...
Could anyone help me out to understand what exactly is happening here. There is an workaround for this problem. Instead of '...' I could use '..<' but this not how the range should be.
Unlike intervals (which have two flavours, half-open or closed), Range is only ever half-open. So when you write 1...5, the ...function increments the right-hand argument in order to create a half-open range 1..<6.
The consequence of this is you can’t have a range that spans the entire length of an integer type, since 1...Int.max will result in an attempt to increment Int.max, and an overflow error. You get a similar error with let s = "hello"; let r = s.startIndex...s.endIndex
All is not lost, however, since you shouldn’t be using ranges anyway, this is a job for ClosedInterval. Since the ... operator is used for both, and defaults to ranges (for overloading precedence reasons) you need to explicitly identify the type:
let i64interval: ClosedInterval = Int64(Int64.min)...Int64(Int64.max)
switch signedValue {
// etc
case i64interval: compressedValue = Int(signedValue)
default: compressedValue = signedValue
}
Look at the documentation for the Range Type. It has the following little nugget of information that I never noticed before:
if T has a maximal value, it can serve as an endIndex, but can never be contained in a Range.
T, in that quote, is the type of value in the Range. So if you have a Range of Ints, the max value of the Int cannot be contained in the Range.
That's why it works if you put the ..< in there, instead of ....
Good question, by the way...
The swift switch statement (tested in Xcode 6.1) allows repeated switch values. See code below which compiles and runs without error. Apparently, the first matching value is the executed case. Subsequent cases are ignored. Is this a bug or feature? If a feature, how is it useful?
class SwitchTest{
enum E {
case one, two, three
}
func test() {
switchStmt(E.one) // outputs: "one, two"
switchStmt(E.two) // outputs: "one, two"
switchStmt(E.three) //outputs: "three, two"
}
func switchStmt(e : E)
{
switch (e){
case .one, .two:
println("one, two")
case .three, .two:
println("three, two")
case .one:
println("one")
case .two:
println("two")
}
}
}
It's only a bug if the documentation says it does one thing but it actually does another. Anything where the documentation remains silent on the matter is technically only a disagreement between implementer and user.
However, in this case, the documentation does not remain silent on the matter, it states quite clearly (my emphasis):
It then executes an appropriate block of code, based on the first pattern that matches successfully.
The reason it's like this is probably to do with the fact that, unlike C, you're not limited to simple matches. You can provide, in the case stanza, single values, lists of single values, ranges, tuples, bindings, additional clauses like where, and the mandatory default case if you haven't already trapped all possible values of the type.
In that sense, it's quite logical. It's just a process of comparing the check value against every case stanza in order and executing the first match, regardless of whether it would match those below as well.
In terms of usefulness, that sequential nature will come in handy if you wanted to specify specific cases at the top and more general ones below, such as with the code:
switch num {
case 2, 3, 5, 7, 11, 13, 17, 19:
println("prime, 1 <= x <= 20");
case 1...20: // don't need 1, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20
println("non-prime, 1 <= x <= 20");
default:
println("x < 1 or x > 20");
}
With the sequential checking nature and specific-to-general-case flow, you can simplify the later cases.
This is a feature--not a bug. It's usefulness is made clear by less simple cases.
Consider this example from the official documentation:
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
println("(0, 0) is at the origin")
case (_, 0):
println("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
println("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
println("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
println("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
Consider that if somePoint had a value of (0,0), all of the cases would be true. And if the tuple were specifically (Int, Int), the final case: case (-2...2, -2...2): could potentially be fully written out (25 combinations) in a comma separated list, more similar to your example. We should want that to disallow our specific case of case (0, 0):, should we?
If we only define our cases in the way we're used to with a standard C-style switch statement, it doesn't make much sense... but then, giving multiple values in a single case isn't a C-style switch statement either.
The example in your question is a bad example of a good feature of the Swift switch statement.
It should be noted though that if we were to reorder the cases here, we could easily end up with switch where it's impossible for one of the cases to ever execute. And it might be nice to get a warning generated if we build this sort of switch statement (for example, what happens if we move case (0, 0): right before the default).
But, consider that the following generates no warning:
for i in 2...1 {
println(i)
}
It should, however, be noted that this will crash: fatal error: Can't form Range with end < start.
The point is, Xcode won't catch absolutely everything, so I'm not sure why we'd pick on switch statements. A simple case like the example in your question might seem easy, but when we consider the totality of the complexity of Swift switch statements, I'm not sure I want a lot of time spent analyzing my switch statements like this.
This should most definitely be a syntax error!
This will be the source of innumerable copy/paste errors.