LoginSignup
2
2

More than 5 years have passed since last update.

Ruby | Enumerable#if_else_map #ruby

Posted at

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 さん、ありがとうございます

参照

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2