Help us understand the problem. What is going on with this article?

【Ruby】なんで.reduce('')なん?とおもったので

More than 5 years have passed since last update.

このnanapiのブログ記事を見たときに

http://blog.nanapi.co.jp/tech/2015/04/02/basic_training_of_ruby/

詳しい内容は記事を読んでいただくとして、こんなコードが出てきました。

def stringify(matrix)
  matrix
    .reduce('') do |result, a|
      result
        << a.map(&:to_s)
          .map { |v| v.rjust(4) }
          .join('|')
        << "\n"
    end
end

表示用に文字列を加工するメソッドなんですが、.reduce('')を使ってるんですよねー。

ん、reduceって例えば

(5..10).reduce() do |sum, value|
  sum + value
end
=> 45

# もしくは
(5..10).reduce(:+)
=> 45

こんな感じで合計値を出すときに使うと便利、みたいな感じじゃないん?と思って調べてみるとこんな記事を発見。

http://railspikes.com/2008/8/11/understanding-map-and-reduce

(5..10).reduce(0) do |sum, value|
  sum + value
end

引数がInitial valueになるんですよねー。上記の記事の解説を引用させていただくと


  • Collection: 5, 6, 7, 8, 9, 10
  • Initial Value: 0
  • Function: add current value to running total
Pass # Collection Value Running Total Return Value
1 5 0 (initializer value) 5
2 6 5 11
3 7 11 18
4 8 18 26
5 9 26 35
6 10 35 45

こういうことなんですね。

そこで冒頭のコードをコメント付きで引用しますと

def stringify(matrix)
  matrix
    .reduce('') do |result, a| # 文字列に畳み込む
      result
        << a.map(&:to_s) # 要素を文字列化して
          .map { |v| v.rjust(4) } # スペースパディングして右寄せして
          .join('|') # | で連結した文字列を結果に詰める
        << "\n" # 改行して区切る
    end
end

文字列を返しているわけなので('')にすると。

ちょい試してみると

(5..10).reduce('') do |sum, value|
  sum.to_s + value.to_s
end  
=> "5678910"

こうなるわけですね。ちなみに

(5..10).reduce(1) do |sum, value|
  sum + value
end  
=> 46

1から始まるわけなので当然結果もプラス1で返ってます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away