LoginSignup
11
3

More than 5 years have passed since last update.

ifをパイプの中で使用する

Last updated at Posted at 2018-10-07

fukuoka.ex代表のpiacereです
今回もご覧いただいて、ありがとうございます:bow:

前回のコラムで、ifが、引数を2つ取る関数であることを解明しました

このことを利用して、パイプの中で、ifを使う方法について解説します

パイプでifの第1引数を渡す

ifは、以下のように、第1引数に条件、第2引数に「do:」と「else:」のキーワードリストを取ります

iex> if( "abc" == "abc", do: "abc is abc", else: "abc is not abc" )
"abc is abc"
iex> if( "abc" == "xyz", do: "abc is abc", else: "abc is not abc" )
"abc is not abc"

これをパイプで書き直すと、こうなります

iex> ( "abc" == "abc" ) |> if( do: "abc is abc", else: "abc is not abc" )
"abc is abc"

なお、パイプで渡す部分をカッコで囲まないと、うまく動きませんので、注意してください

iex> "abc" == "abc" |> if( do: "abc is abc", else: "abc is not abc" )
false
iex> "abc" == "xyz" |> if( do: "abc is abc", else: "abc is not abc" )
false

パイプで繋いだ処理の中でifを使う

以下のような、0~10までの数字列のうち、3で割り切れるものだけ、trueを返す処理があったとします

iex> 0..10 |> Enum.map( &( rem( &1, 3 ) == 0 ) )
[true, false, false, true, false, false, true, false, false, true, false]

この処理の中で、ifを挟むと、以下のような、trueになった数字だけをピックアップできます

iex> 0..10 |> Enum.map( &( ( rem( &1, 3 ) == 0 ) |> if( do: &1 ) ) )
[0, nil, nil, 3, nil, nil, 6, nil, nil, 9, nil]

nilをEnum.filterで除去すると、こんな感じになります

iex> 0..10 |> Enum.map( &( ( rem( &1, 3 ) == 0 ) |> if( do: &1 ) ) ) |> Enum.filter( &( &1 != nil ) )
[0, 3, 6, 9]

ifをパイプ中で使う方法が、お分かりになったでしょうか?

ifをパイプで書かなくてもいいし、ifを使わなくてもいい

なお、このサンプルは、以下のように、普通のif文で書き直すこともできます

iex> 0..10 |> Enum.map( &( if rem( &1, 3 ) == 0, do: &1 ) ) |> Enum.filter( &( &1 != nil ) )
[0, 3, 6, 9]

1行ifの強力さを実感できますね

更に単純化すると、以下の通りです

iex> 0..10 |> Enum.filter( &( rem( &1, 3 ) == 0 ) )
[0, 3, 6, 9]

ifが無くなってしまいました:sweat:

全てのケースが、ここまで単純化できるかは、何とも言えませんが、Enumをマスターしていくと、データの塊を処理する際に、if文での判定が不要になっていくニュアンスを、ここから何となく受け取っていただけたら幸いです

p.s.「いいね」よろしくお願いします

よろしければ、ページ左上の image.pngimage.png のクリックをお願いしますー:bow:

11
3
1

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
11
3