Swift で、 Ruby の each_cons(n)
みたいに、n個ずつずらしながら扱いたいときのTips。
コード
extension Array {
func eachPair() -> [(Element, Element)] {
return zip(self, self.dropFirst()).map({ ($0.0, $0.1) })
}
func eachCons(_ n: Int) -> [ArraySlice<Element>] {
return indices.dropLast(n-1).map({ self[$0...$0+n-1] })
}
func eachSlice(_ n: Int) -> [ArraySlice<Element>] {
return stride(from: 0, through: count - 1, by: n).map({ self[($0..<$0+n).clamped(to: indices)] })
}
}
使用
let sample = [1, 2, 3, 4, 5, 6]
sample.eachPair() // [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
sample.eachCons(3) // [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
sample.eachCons(6) // [[1, 2, 3, 4, 5, 6]]
sample.eachCons(7) // []
sample.eachSlice(2) // [[1, 2], [3, 4], [5, 6]]
sample.eachSlice(4) // [[1, 2, 3, 4], [5, 6]]
sample.eachSlice(7) // [[1, 2, 3, 4, 5, 6]]
eachPair
はタプルで返るようになってます。
eachCons
で大きい値を与えた場合、空の配列が返ります。
補足
-
eachCons(0)
など0以下の値を与えるとエラーになるので、工夫しても良いかも。 -
eachPair()
は、 Ruby で言うeach_pair
とは異なるので注意。 - extension は
Collection
ではなくArray
に対して書いています。Dictionary
などには使用しないので。
環境
- Swift 5.0
参考
- Ruby の配列で n 個ずつの要素を扱いたい
https://qiita.com/yynozk/items/022b0dfcb52a2cf30eca - Ruby のリファレンス
https://ref.xaio.jp/ruby/classes/enumerable/each_cons
https://ref.xaio.jp/ruby/classes/hash/each - コードの参考元
https://stackoverflow.com/questions/39756309
https://gist.github.com/khanlou/f27b34f28b21b4834a758913e06a5f3b
https://stackoverflow.com/questions/27984914/swift-equivalent-to-each-slice