Swift uses Index
when accessing an element in a Collection
like array and dictionary.
For Array
specifically, the index is guaranteed to behave the same as in good-ol C. That is, it starts from zero, and increments by one at every element. So things like array[2]
is predictible.
For other collections, though, there is no such guarantee. In those cases, you need to create a valid index via index APIs. Doing largeSqs[50]
is ill-formed because you are not accessing it with a valid index. In your case, you start from the start index, and offset it by 50 elements:
let startIndex = largeSqs.startIndex
let index = largeSqs.index(startIndex, offsetBy: 50)
largeSqs[index] // 1104601
This is how you generally traverse a collection, you start from a valid index, like start index and end index, and then move/offset around.
One caveat of using lazy is that the computation kicks in every time you offset the index, which is quite wasteful. If you calculate the index multiple times, you may want to convert the entire lazy chain into a simple Array
first.
In this particular case, we can even do one better. Note that once the filter condition (element > 1000
) is met, it continues to be satisfied until the end of the collection. So we can simply find the first element that meets the criteria, and the get a slice of the collection:
// The first index that meets the condition.
// If no element meets the condition, then set it to `endIndex`
let firstIndex = allNmbrs.firstIndex { $0 > 1000 } ?? allNmbrs.endIndex
let largeSqs = allNmbrs[firstIndex...] // Every element after `firstIndex`, inclusive
.lazy // Make it lazy
.map { (element) -> Int in
print("map", element)
return element * element
}
let startIndex = largeSqs.startIndex
let index = largeSqs.index(startIndex, offsetBy: 50)
largeSqs[index] // 1104601
PS
You can put code in triple tick mark
```
Like this
```
and it will be rendered
Like this