Search code examples
swiftlazy-sequences

How do I access a lazy sequence with an index?


I noticed this behaviour regarding lazy sequences today:

// filtered will be [2, 4, 6, 8]
let filtered = [1,2,3,4,5,6,7,8].lazy.filter { $0 % 2 == 0 }
print(filtered[2]) // expecting 6, but prints 3

I understand why it gives me 3. The subscript probably only knows about the sequence underlying the lazy wrapper, so it returns the element from the original unfiltered sequence. However, how would I otherwise access the third element?

Context:

I am building a table view from a Realm query result, which I applied an additional filter because the filter I am trying to do isn't supported by Realm. Therefore I now have a LazyFilterSequence<Results<MyRealmObject>>. In cellForRowAt, I need to access the lazy sequence by index so that I know what to show in each table cell.


Solution

  • You can access them in a similar fashion to how you access a string by an integer, i.e. using index(_:offsetBy:):

    filtered[filtered.index(filtered.startIndex, offsetBy: 2)]
    

    Accessing a lazy filter sequence is quite similar to accessing a string in that both are not O(1).

    Alternatively, drop the first n items and then access the first item:

    filtered.dropFirst(2).first
    

    But I prefer the first one as "dropping" things just to access a collection, in my mind, is quite weird.