Roman
Roman

Reputation: 1498

How to convert Sequence to Array or is there an end of Sequence in Swift?

According to the documentation:

init(_ s: S) where Element == S.Element, S : Sequence
Creates an array containing the elements of a sequence.

struct Test: IteratorProtocol, Sequence {
    let id: Int

    init(_ id: Int) {
        self.id = id
    }

    mutating func next() -> Test? {
        id < 10 ? Test(id + 1) : nil
    }
}

let test = Test(5)
let arr = Array(test)

It compiles. And doesn't even throw any runtime errors.
But instead of getting the array [5, 6, 7, 8, 9] as a result, I get an infinite loop! next() is called infinitely many times.
I thought that nil in next() is a natural indicator of the end of sequence. But apparently it's not.

Upvotes: 1

Views: 3694

Answers (3)

Roman
Roman

Reputation: 1498

Appears, there is a built-in function, that completely suits the logic of my initial question in this post.

sequence(first:next:)
Returns a sequence formed from first and repeated lazy applications of next.

struct Test {
    var id: Int

    init(_ id: Int) {
        self.id = id
    }
}

let seq = sequence(first: Test(5), next: { test in
    let id = test.id + 1
    return id < 10 ? Test(id) : nil
})

let arr = Array(seq)

Upvotes: 0

Harsh
Harsh

Reputation: 2908

It should be something like this

struct Test: IteratorProtocol, Sequence {
    var id: Int

    init(_ id: Int) {
        self.id = id
    }

    mutating func next() -> Test? {
       defer { id += 1 } 
       return id < 10 ? self : nil
    }
}

print(Array(Test(6)))

Another example

 struct Countdown: Sequence, IteratorProtocol {
     var count: Int

     mutating func next() -> Int? {
         if count == 0 {
             return nil
         } else {
             defer { count -= 1 }
             return count
         }
     }
 }

 let threeToGo = Countdown(count: 3)
 for i in threeToGo {
     print(i)
 }
 // Prints "3"
 // Prints "2"
 // Prints "1"

Upvotes: 1

Alexander
Alexander

Reputation: 63271

self.id never changes, so it never reaches 10.

Upvotes: 2

Related Questions