OnlyFunc

Why you should use zip() instead of enumerated()

When working with Collections in Swift, sometimes we need to access both the index and the value of the element. This can be achieved using .enumerated(). But there are more preferable way of doing it by using zip(collections, collections.indices).

Using enumerated()

The enumerated() method will transforms a collection into a sequence of index-value pairs.

let fruits = ["Apple", "Banana", "Cherry"]

for (index, fruit) in fruits.enumerated() {
    print("\(index): \(fruit)")
}

But, the first one isn't actually the index of element. It's a counter that start with 0. This can mislead when you work with a collection that is not starting from 0 such as ArraySlice

let slice = fruits[1...] // ["Banana", "Cherry"]
for (index, fruit) in slice.enumerated() {
    print("\(index): \(fruit)") // Index starts from 0, not 1
}

Using zip(collection.indices, collection)

Instead of using .enumerated(), we can combine zip with indices to get the actual index-value pairs.

for (index, fruit) in zip(fruits.indices, fruits) {
    print("\(index): \(fruit)")
}

// or

zip(fruits.indices, fruits).forEach { index, value in 
    print("\(index): \(fruit)")
}

The advantage of using zip is we now have an accurate index even when we work with slices and non-zero based collections

let slice = fruits[1...] // ["Banana", "Cherry"]
for (index, fruit) in zip(slice.indices, slice) {
    print("\(index): \(fruit)") // Correctly prints 1, 2
}

For correctness, it's better to use zip with indices rather than using enumerated(). However, .enumerated() remains an convenient option for simple cases where the index doesn't need to match the collection's actual indices.

#array #collections #swift