Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array initialization riddle with repeatedValue as a sequence, Swift

Trying to pass a generated sequence (could be more complex struct or func values), like generation of some key strings during array initialize.

Here's an array initialization string:

let MyArray: Array<Int> = Array<Int>(count: 100, repeatedValue:(for i in 0...99))
// it does not work, I am doing it wrong :(
// instead of (for i in 0...99) could be anything, a key sequence generator

Here's what documentation says:

/// Construct a Array of `count` elements, each initialized to
/// `repeatedValue`.
init(count: Int, repeatedValue: T)

What would be a proper way to replace the "T" with generated or sequenced values. Or should I not bother with this and make array a variable and just fill it later on?

Thanks.

like image 429
thinkswift Avatar asked Nov 30 '25 06:11

thinkswift


2 Answers

Array has a constructor that takes a sequence as argument:

init<S : SequenceType where T == T>(_ s: S)

Examples: A range is a sequence:

let a1 = Array(0 ..< 10)
println(a1)
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

A map takes a sequence and returns an array:

let a2 = map( 0 ..< 10) { i in i*i }
println(a2)
// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Example with a custom sequence type (copied from https://codereview.stackexchange.com/a/60893/35991):

struct FibonacciSequence : SequenceType {
    let upperBound : Int

    func generate() -> GeneratorOf<Int> {
        var current = 1
        var next = 1
        return GeneratorOf<Int>() {
            if current > self.upperBound {
                return nil
            }
            let result = current
            current = next
            next += result
            return result
        };
    }
}

let fibseq = FibonacciSequence(upperBound: 100)
let a3 = Array(fibseq)
println(a3)
// [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

Update for Swift 2:

let a1 = Array(0 ..< 10)
print(a1)
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

let a2 = (0 ..< 10).map { i in i*i }
print(a2)
// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

struct FibonacciSequence : SequenceType {
    let upperBound : Int

    func generate() -> AnyGenerator<Int> {
        var current = 1
        var next = 1
        return anyGenerator {
            if current > self.upperBound {
                return nil
            }
            let result = current
            current = next
            next += result
            return result
        };
    }
}

let fibseq = FibonacciSequence(upperBound: 100)
let a3 = Array(fibseq)
print(a3)
// [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
like image 84
Martin R Avatar answered Dec 01 '25 20:12

Martin R


This syntax is not valid:

Array<Int>(count: 100, repeatedValue:(for i in 0...99))

If you want to keep you array as let and initialise it with custom values you can do the following:

let myArray: Array<Int> = {
    var myArray: Array<Int> = []
    for i in 0...99 {
        myArray.append(i)
    }

    return myArray
}()

This means that myArray will have value of the result of unnamed closure that is executed right after it declaration.

like image 31
Kirsteins Avatar answered Dec 01 '25 20:12

Kirsteins