5

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?

neoneye
  • 50,398
  • 25
  • 166
  • 151

2 Answers2

6
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")]
neoneye
  • 50,398
  • 25
  • 166
  • 151
Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • very elegant solution. Thank you Kevin – neoneye Sep 28 '16 at 19:46
  • 1
    I'm glad someone has been giving this some thought. Can we generalize this so that we don't have to hard-code the `2` of `each_cons(2)`? – matt Sep 28 '16 at 19:46
  • However, Swift doesn't have a general version of `zip`: this only works for pairs. – jscs Sep 28 '16 at 19:46
  • 1
    @JoshCaswell Correct. I have a more general solution but it is sort of horribly inefficient. – matt Sep 28 '16 at 19:47
2

This is the general solution I came up with, but it seems sort of horribly inefficient. To implement each_cons(n), set my clump to n:

        let arr = [1,2,3,4,5,6,7,8]
        let clump = 2
        let cons : [[Int]] = arr.reduce([[Int]]()) {
            memo, cur in
            var memo = memo
            if memo.count == 0 {
                return [[cur]]
            }
            if memo.count < arr.count - clump + 1 {
                memo.append([])
            }
            return memo.map {
                if $0.count == clump {
                    return $0
                }
                var arr = $0
                arr.append(cur)
                return arr
            }
        }
matt
  • 515,959
  • 87
  • 875
  • 1,141