0

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.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • 2
    Related: [Swift lazy subscript ignores filter](https://stackoverflow.com/q/54294501/1187415). – Martin R Jul 07 '20 at 05:15
  • 1
    Remotely related: [Why does filter(_:)’s predicate get called so many times when evaluating it lazily?](https://stackoverflow.com/q/41940243). – Martin R Jul 07 '20 at 06:54
  • @MartinR So both question and answer here are a pure duplicate. Why not mark as a duplicate? – matt Jul 07 '20 at 12:29
  • @matt: Because I was too lazy(!) to read the other Q&A in detail and check if it qualifies as an exact duplicate. – Martin R Jul 07 '20 at 12:42

1 Answers1

1

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.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • @matt But then you would have to use a "1 based index" don't you? I think that's a recipe for tons of off-by-one errors, but maybe that's just me... :) – Sweeper Jul 07 '20 at 04:16