'How to enumerate collections with every two elements, not [[1, 2], [3, 4]], but [[1,2], [2, 3], [3, 4]] in Swift [duplicate]

How to enumerate collections(like [1,2,3,4]) with every two elements, not [[1, 2], [3, 4]], but [[1,2], [2, 3], [3, 4]] in Swift.

Prefer a method like forEach, but forEachTwo in this question:

collections.forEachTwo { (first, second) in
    // do something.
}


Solution 1:[1]

for (first, second) in zip(elements, elements.dropFirst()) {
    print(first, second)
}

forEach (or a derivative) is bad here for iteration. It is better to use a for-in. forEach has side-effects (breaking FP) and subtle weirdnesses with Swift (breaking good Swift). for-in is more powerful and cleaner. But the creation of the actual sequence is classic FP: zip with dropFirst.

Note that this is a sequence of tuples, not arrays as you wrote. I don't think you want arrays here, given the syntax you suggest (though you could achieve that with a map if you did).

You can get the syntax you suggest with this, but it's not as flexible as the for-in, and has subtle edge cases (for example if the closure includes a return it behaves like a continue):

extension Sequence {
    func forEachTwo(_ f: ((Element, Element) -> Void)) {
        for element in zip(self, dropFirst()) {
            f(element.0, element.1)
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1