前回は「filterの使い方」「mapの使い方」を書きました。
今回はreduceの使い方を書きます。
reduceは配列の各要素に次々に関数を適用して、最後に得られた値を返す関数です。
[1, 2, 3, 4, 5]
という配列の合計を求めるコードを書いていきます。
for in
文を使った場合です。
var result = 0
for n in [1, 2, 3, 4, 5] {
result += n
}
println(result)
実行結果は15
となります。
次にreduceを使った場合です。
ドキュメントを読むと、func reduce<U>(initial: U, combine: (U, T) -> U) -> U
とあります。
initial
つまり初期値を指定するということがわかります。for in
文の例のresult = 0
にあたります。
UとTを与えてUを返せばいいということがわかります。
このとおり書き換えると次のようになります。
println([1, 2, 3, 4, 5].reduce(0, combine: {(n, m) -> Int in return n + m}))
1行になりました。
これもfilterやmapのときと同様に短く書くことができます。今回は(U, T)
の2つの引数をとるため$0
と$1
となります。
println([1, 2, 3, 4, 5].reduce(0){$0 + $1})
文字列の配列でも同様の処理ができます。
println(["w", "o", "r", "l", "d"].reduce("Hello "){$0 + $1}) // Hello world
最後にfilter、map、reduceを使ったコードを示します。
税抜き価格の配列
[300, 400, 1000, 200, 4000, 3000, 100]
から、税抜き価格が1000円以上のものを選んだときの税込み価格の合計は何円か。ただし消費税は8%とする。
println([300, 400, 1000, 200, 4000, 3000, 100].filter{$0 >= 1000}.map{$0 * 1.08}.reduce(0){$0 + $1}) // 8640.0
filter、map、reduceを使ったコードになりました。
分解してみてみます。
はじめにfilterです。1000以上のときtrueを返すようにしています。
[300, 400, 1000, 200, 4000, 3000, 100].filter{$0 >= 1000}
この実行結果は、[1000, 4000, 3000]
です。
次にmapです。それぞれの要素に1.08をかけます。
[300, 400, 1000, 200, 4000, 3000, 100].filter{$0 >= 1000}.map{$0 * 1.08}
この実行結果は、[1080.0, 4320.0, 3240.0]
です。
最後にreduceで、それぞれの要素の合計を求めます。
[300, 400, 1000, 200, 4000, 3000, 100].filter{$0 >= 1000}.map{$0 * 1.08}.reduce(0){$0 + $1}
この実行結果は8640.0
になります。
このようにメソッドチェインを使って処理をつなげて書くことができます。