Ruby | Enumerable#if_else_map #ruby
概要
Enumerable#if_else_map を妄想したら @cielavenir さんが秒速( 与沢級 )で作ってくれた
経緯
map 内で条件に合わせて二種類の変換をしたい場合。
こんな感じで、 map のブロック内で三項演算子を使ったり if を使ったりすると思う。
require 'pp'
pp [*1..4].map { |e| e.odd? ? 'odd' : 'even' }
class String
def vowel?
!!(self =~ /[aiueo]/)
end
end
pp [*?a..?z].map { |e| e.vowel? ? "#{e} is vowel" : "#{e} is not vowel" }
- 出力
["odd", "even", "odd", "even"]
["a is vowel",
"b is not vowel",
"c is not vowel",
"d is not vowel",
"e is vowel",
"f is not vowel",
"g is not vowel",
"h is not vowel",
"i is vowel",
"j is not vowel",
"k is not vowel",
"l is not vowel",
"m is not vowel",
"n is not vowel",
"o is vowel",
"p is not vowel",
"q is not vowel",
"r is not vowel",
"s is not vowel",
"t is not vowel",
"u is vowel",
"v is not vowel",
"w is not vowel",
"x is not vowel",
"y is not vowel",
"z is not vowel"]
しかし、コレクションパイプラインの操作イメージからするとなんとなくしっくりこなかったり。
「こんな感じのがあったほうがしっくりするかな?」、と下記のようなインターフェースをツイートしたところ、
[*1..10].if_else_map(&:odd,->{|odd|'奇数'},->{|even|偶数"})
@cielavenir さんが秒速で実装してくれました。
※ 我ながら if_else_map という名前が微妙だけど、とりあえず話題を進める上で伝わりやすいのでそのまま話をすすめた
Enumerable#if_else_map
私が色んな文法を試してる 実用的ではない 遊び場的な Utility 'tbpgr_utils' にプルリクをいただいた。
if_else_map pull request
if_else_map のコード
module Enumerable
def if_else_map(predicate,proc_t,proc_f)
map{|e|predicate.call(e) ? proc_t.call(e) : proc_f.call(e)}
end
end
if_else_map を使ってみる
- 分岐条件
- if の時の変換ルール
- else の時の変換ルール
が分割されてなんとなく気分が良くなった。
require 'tbpgr_utils'
require 'pp'
pp [*1..4].if_else_map(
:odd?.to_proc,
->(odd){'odd'},
->(even){'even'}
)
puts
class String
def vowel?
!!(self =~ /[aiueo]/)
end
end
pp [*?a..?z].if_else_map(
:vowel?.to_proc,
->(alph){ "#{alph} is vowel" },
->(alph){ "#{alph} is not vowel" }
)
- 出力
["odd", "even", "odd", "even"]
["a is vowel",
"b is not vowel",
"c is not vowel",
"d is not vowel",
"e is vowel",
"f is not vowel",
"g is not vowel",
"h is not vowel",
"i is vowel",
"j is not vowel",
"k is not vowel",
"l is not vowel",
"m is not vowel",
"n is not vowel",
"o is vowel",
"p is not vowel",
"q is not vowel",
"r is not vowel",
"s is not vowel",
"t is not vowel",
"u is vowel",
"v is not vowel",
"w is not vowel",
"x is not vowel",
"y is not vowel",
"z is not vowel"]
Wrap up
- 特にこの記法を押していくつもりもない。試してみたかっただけ
- case 版、とかも面白いかも
- @cielavenir さん、ありがとうございます