Search code examples
arraysrubyswiftenumeratorequivalent

Swift equivalent of Ruby's "each_cons"


Ruby

Ruby has each_cons that can be used like this

class Pair
    def initialize(left, right)
        @left = left
        @right = right
    end
end
votes = ["a", "b", "c", "d"]
pairs = votes.each_cons(2).map { |vote| Pair.new(*vote) }
p pairs
# [#<Pair @left="a", @right="b">, #<Pair @left="b", @right="c">, #<Pair @left="c", @right="d">]

Swift

The same code in swift, but without the each_cons function

struct Pair {
    let left: String
    let right: String
}
let votes = ["a", "b", "c", "d"]
var pairs = [Pair]()
for i in 1..<votes.count {
    let left = votes[i-1]
    let right = votes[i]
    pairs.append(Pair(left: left, right: right))
}
print(pairs)
// [Pair(left: "a", right: "b"), Pair(left: "b", right: "c"), Pair(left: "c", right: "d")]

How can this swift code be made shorter or simpler?


Solution

  • zip(votes, votes.dropFirst())
    

    This produces a sequence of tuples.

    Example

    struct Pair {
        let left: String
        let right: String
    }
    let votes = ["a", "b", "c", "d"]
    let pairs = zip(votes, votes.dropFirst()).map {
        Pair(left: $0, right: $1)
    }
    print(pairs)
    // [Pair(left: "a", right: "b"), Pair(left: "b", right: "c"), Pair(left: "c", right: "d")]