LoginSignup
3

More than 3 years have passed since last update.

posted at

updated at

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

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:

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
What you can do with signing up
3