Treat a Single Integer Value as a Range in Swift

how to include range for eg 'if numbers are between 1 to 5' in swift

You could just use two conditions to check whether it's in bounds:

if myPercent >= 1 && myPercent <= 5 {
...
}

Swift: Cannot convert value of type 'RangeInt' to specified type 'Int'

Your code doesn't compile because you have used [] around the range, which creates an array. [1..<10] is an array of ranges. The for loop is then iterating over that array, which has only one element - the range 1..<10.

This is why i is of type Range<Int>. It is the range, not the numbers in the range.

Just remove the [] and both of your code would work. You can iterate over ranges directly (in fact, anything that conforms to the Sequence protocol), not just arrays. You can even write the range inline with the loop:

for i in 0..<10 {
print(i * i)
}

Why are there so many types of <Int> in Swift?

You are looking at this the wrong way, the word Range and ClosedRange in the types Range<Int> and ClosedRange<Int> are not words that modify Int, as if they are different "flavours" of Int. It's the opposite - Range<Bound> and ClosedRange<Bound> are generic types, and Range<Int> can be a considered the specific "type" of Range that has Int as its bounds. You can also have Range<Float> or Range<UInt8> for example.

Can I use the range operator with if statement in Swift?

You can use the "pattern-match" operator ~=:

if 200 ... 299 ~= statusCode {
print("success")
}

Or a switch-statement with an expression pattern (which uses the pattern-match
operator internally):

switch statusCode {
case 200 ... 299:
print("success")
default:
print("failure")
}

Note that ..< denotes a range that omits the upper value, so you probably want
200 ... 299 or 200 ..< 300.

Additional information: When the above code is compiled in Xcode 6.3 with
optimizations switch on, then for the test

if 200 ... 299 ~= statusCode

actually no function call is generated at all, only three assembly instruction:

addq    $-200, %rdi
cmpq $99, %rdi
ja LBB0_1

this is exactly the same assembly code that is generated for

if statusCode >= 200 && statusCode <= 299

You can verify that with


xcrun -sdk macosx swiftc -O -emit-assembly main.swift

As of Swift 2, this can be written as

if case 200 ... 299 = statusCode {
print("success")
}

using the newly introduced pattern-matching for if-statements.
See also Swift 2 - Pattern matching in "if".

How to quickly check if an Integer lies within a given range

You can create a range and check if it contains x:

let contains = (lowerBounds...upperBounds).contains(x)

e.g.:

let successful = (200..<300).contains(httpStatusCode)

swift convert RangeInt to [Int]

You need to create an Array<Int> using the Range<Int> rather than casting it.

let intArray: [Int] = Array(min...max)

iOS: Can't get first item value from RangeCGFloat

first is a method of the Collection protocol (and last a method of BidirectionalCollection). A Range is a (bidirectional) collection only if the underlying element type is an integer type, or any other type that conforms to the Strideable protocol with an integer stride. Example:

let intRange = 1..<10
print(intRange.first!) // 1
print(intRange.last!) // 9

A range of floating point numbers is not a collection, so there is no first or last method. But you can retrieve the lower/upper bound:

let range: Range<CGFloat> = 1.0..<3.22
print(range.lowerBound) // 1.0
print(range.upperBound) // 3.22

Swift Define Array with more than one Integer Range one liner

As MartinR mentioned, you could simply concenate arrays using the + operator; and if this method is an answer for you, than this thread is a duplicate (see MartinR:s link), and should be closed.


If you explicitly wants to initialize an Int array using several ranges at once (see e.g. hola:s answer regarding array of ranges), you can make use of reduce as follows

let arr = [1...5, 11...15].reduce([]) { $0.0 + Array($0.1) }

Or, alternatively, flatten

var arr = Array([1...5, 11...15].flatten())

Both the above yields the following result

print(arr.dynamicType) // Array<Int>
print(arr) // [1, 2, 3, 4, 5, 11, 12, 13, 14, 15]

Switch case with range

This should work.

private func calculateUserScore() -> Int {
let diff = abs(randomNumber - Int(bullsEyeSlider.value))
switch diff {
case 0:
return PointsAward.bullseye.rawValue
case 1..<10:
return PointsAward.almostBullseye.rawValue
case 10..<30:
return PointsAward.close.rawValue
default:
return 0
}
}

It's there in the The Swift Programming Language book under Control Flow -> Interval Matching.

How to interpolate from number in one range to a corresponding value in another range?

The map function on collections is going to do something very different. It applies a mapping function to each element of a collection and returns a new collection based on the results.

What you're looking for would be:

func map(minRange:Int, maxRange:Int, minDomain:Int, maxDomain:Int, value:Int) -> Int {
return minDomain + (maxDomain - minDomain) * (value - minRange) / (maxRange - minRange)
}

print(map(minRange: 0, maxRange: 1800000, minDomain: 0, maxDomain: 3000, value: 200000))

With only a little more work you can make it generic over all integer types:

func map<T:IntegerArithmetic>(minRange:T, maxRange:T, minDomain:T, maxDomain:T, value:T) -> T {
return minDomain + (maxDomain - minDomain) * (value - minRange) / (maxRange - minRange)
}

Another option would be to take advantage of the Swift Range type to make calling more succinct:

func map<T:IntegerArithmetic>(range:Range<T>, domain:Range<T>, value:T) -> T {
return domain.lowerBound + (domain.upperBound - domain.lowerBound) * (value - range.lowerBound) / (range.upperBound - range.lowerBound)
}

map(range:0..<3000, domain:0..<180000, value: 1500)


Related Topics



Leave a reply



Submit