読者です 読者をやめる 読者になる 読者になる

器用貧乏です。はげたかです。日記です。

どうも、はげたかです。今まで器用貧乏に生きてきました。ジェネラリスト・フルスタックエンジニアを目指しています。

今日の一言:カテゴリ分けをしっかりしたらPVあがるかな?

気になる記事があったので、やってみた -> Haskellの勉...

はじめに

適当にネットサーフィンをしていたら、ちょっと気になる記事を発見した。

HaskellとかElixirに惹かれたのではなくて、ただRubyのコードに興味が出た。

さて、くだらない例だけど、数のリストに何か(map)して条件を満たすものを抜き出して(filter)、最後に足す(fold)みたいなこと

これをRuby のコードで表現すると、以下になる。(引用)

irb> (1..10).map{|x| x + 1 }.select{|n| n.even? }.reduce(0){|a, b| a + b }
=> 30

ふぇええ、一見何しているか分かんない。自分の技術力の低さに驚く。と、負けじとコードを読み解いていくとする。

2.1.1 :001 > (1..10).map{|x| x + 1 }
 => [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 
# ふむふむ、1を足すのか?

2.1.1 :003 > (1..10).map{|x| x + 1 }.select{|n| n.even? }
 => [2, 4, 6, 8, 10] 
# その中から偶数を取り出すのね

2.1.1 :004 > (1..10).map{|x| x + 1 }.select{|n| n.even? }.reduce(0){|a, b| a + b }
 => 30 

# ん? a + bをするのか...?予測では、aはsumみたいなもので、reduceというぐらいだから、bはその前の配列[2, 4, 6, 8, 10] を1つずつ取り出しているのかな
# 形としては、sum += bみたいな感じかな
# 計算の順序がわからないので、簡単なものを出力させてみる

2.1.1 :027 > [1, 2, 3, 4].reduce(0){|a, b| puts a, b}
0
1

2

3

4

# [1, 2, 3, 4]の配列を1つずつ取り出して、reduceしているのか。納得。
# 自分が予測していたものと一緒だった。

2.1.1 :004 > (1..10).map{|x| x + 1 }.select{|n| n.even? }.reduce(0){|a, b| a + b }
 => 30 
# つまりこのコードは、1..10を配列にして、偶数のものを配列で抜き出して、a(初期値:引数の0)に足してるのだ。
# 今更だけど、reduce(0)は初期値を入れているのね。

# また追加するけど、reduceというものを知らなければ俺はここでeachを使っていたな.

> (1..10).map{|x| x + 1 }.select{|n| n.even? }.each do |n, sum=0| sum += n end 
> sum 
=> 30

# これだと見栄えが悪い、reduceってすげぇえ〜。現場のエンジニアさんってすごいな!!!!!!!

一つ一つ紐解いていくと、理解できることがわかった。ワンライナーってすごいな、自分が普通に書くと以下になる気がする。(趣旨がずれているが)

sum = 0
(1..10).map{|x|
  if x.even?
     sum += x
  end
  puts sum
}

書いてみたけど、出力だけならこれでおkね。今回、mapを覚えたからちょっと使ってみたけど、これは絶対違う。戻り値が変だからこれの答えは違うな。。

sum = 0
for i in 1..10
  sum += i if x.even?
end
sum

これなら答えが一緒だ。趣旨(数のリストに何か(map)して条件を満たすものを抜き出して(filter)、最後に足す(fold)みたいなこと)がずれているけど...

さいごに

>  (1..10).map{|x| x+1 }.select{|n| n.even? }.reduce(0){|a, b| a + b}
=> 30

最後に、 x + 1をしている理由がわからないのだが...ん〜〜??

2.1.1 :020 > (1..10).map{|x| x }.select{|n| n.even? }.reduce(0){|a, b| a + b}
 => 30 

これじゃダメなのかな?

得たもの

今回このコードを読んで、様々なことを学べた。

Rubyの良いところ

よく、Rubyに関する記事を見ると、「mapバンザーイ!」「これがあるから良いよね」みたいのを見掛ける。今まで、それに接しなかったため、mapの良さが分からなかったが、今回ので"少し"理解できた。

mapというものは、数のリストを配列化?するもので、メソッドチェーン(あっているかわからないけど)をして、selectや足したりなどできるテクニックなのかな。これはシンプルに書けるし、今回みたいにワンライナーで様々な処理ができるからカッコイイ!

自分で書いてみる

一つ一つ紐解いていくことで、理解をしていく。多分プログラミングをするならこの作業は重要になってくる。わからないことがあるとこういうプロセスを踏んで理解していくが、たまにわかったつもりで済ます部分があるため、今回自分でやってみてよかったな、と思った。

ワンライナーのコードからたくさんのことが学べた!よかったなあ〜

※ 勝手に解釈をしている部分があるので、この記事を頼りにしないでね。

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例

パーフェクトRuby

パーフェクトRuby