配列をmap
するとき,map
に与えるクロージャで配列のインデックス値を使いたくなる時がある.
例えばこんなクロージャ.
{(v:Int, i:Int) in v << (24 - (i * 8))}
そして,array.map(f, 0)
などと使いたくなる気分.ですが,これってなんだかmap
の伝統を壊してるような気がしていやなんですよね.パッと見,なんだこれ?ってなりそうで.
APIとしてよさそうなのは,Schemeのように複数のリストを引数にとれるmap関数でしょうか.
というわけで,早速,extensionしてみました.
extension Array {
func map<U>(other: [T], transform: (T, T) -> U) -> [U] {
assert(self.count == other.count)
var v = [U]()
for i in 0 ..< self.count {
v.append(transform(self[i], other[i]))
}
return v
}
}
この例では,自分ともう一個の配列に対してクロージャを適用します.両配列サイズは同じと仮定.
[1,2,3,4].map([5,6,7,8]){$0 + $1}
// ==> [6,8,10,12]
そして,当初の配列のインデックス値を使いたいときはこんな感じ.
let array = [1,2,3,4]
let indices = [0,1,2,3]
array.map(indices) {$0 << (24 - ($1 * 8))}
2つ以上の配列を使いたいときは,上記を元にどんどん定義していけばよさそうです.
個人的にExtensionにハマっているのと,Trailing Closureを使いたいがために上のようなことやりましたが,別に配列に組み込まなくても独立なmap関数として定義したほうがいいかもしれません.
人によっては,
map(function, array0, array1,...)
のほうが見慣れてるかも.しかも可変引数で定義できそうだし.
配列のサイズが異なる場合はどうするのがいいのかなぁ..