Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

each_with_objectで遊ぶ

each_with_objectには、文字通りオブジェクトを持たせてeachをブンまわすことができます。
以前も扱った内容ですが……ちょっと理解が深まったので再度。

文字列

> ('a'..'z').each_with_object("") {|i,a| a << i.upcase}
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

p ("a".."z").each_with_object(".png").map(&:+)
["a.png", "b.png", "c.png",  ...(中略)... "y.png", "z.png"]
=> ["a.png", "b.png", "c.png",   ...(中略)..."y.png", "z.png"]

正規表現

> %w(foo bar fizz buzz).each_with_object(/fizz/) {|i,rg| puts rg === i }
false
false
true
false
=> /fizz/

配列

これはあまり旨味がないかもしれません。mapとかありますし。

> (1..10).each_with_object([2,9]) {|i,a| puts  (i * (a[0]) + a[1]) }
11
13
15
17
19
21
23
25
27
29
=> [2, 9]

あとは

> (1..100).each_with_object([]) {|i,a| a << i * 2 }
=> [2, 4, 6, 8, 10, 12, 14, 16, ...(中略)... 194, 196, 198, 200]

この例程度の話であれば

> (1..100).each_with_object(2).map(&:*)
=> [2, 4, 6, 8, 10, 12, 14, 16, ...(中略)... 194, 196, 198, 200]

と書き換えできます。
少しだけ文字数が減りました。

数値

> (1..10).each_with_object(2) {|i,a| puts a += i}
3
4
5
6
7
8
9
10
11
12
=> 2

sleep

rubyは何でもobjectです。
というわけで、何に使うのか検討もつきませんが、sleepを持たせる事も可能です。
最初の一回だけ待ち、あとは数値を返すだけ。*1

> (1..5).each_with_object(sleep(5)) {|i,a| puts i; p a}
1
5
2
5
3
5
4
5
5
5
=> 5

*1:p sleep 5の返り値は5です