Scalaのコレクションクラスなどで利用することができるプレースホルダ(「_」)について、ちょっと調べてみたのでまとめてみました。
まずはfilterメソッドによる簡単なサンプル
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def filter (p: (A) ⇒ Boolean): List[A] |
省略しないと
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val list = (1 to 10).toList | |
println(list.filter((i:Int) => (i % 2 == 0))) |
省略すると
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val list = (1 to 10).toList | |
println(list.filter(_ % 2 == 0)) |
クラスのリストでも同じことができます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Something(id:Int, something:String) | |
object Hello extends App { | |
val list = Something(1, "test") :: Something(2, "past") :: Something(3, "future") :: Nil | |
println(list.filter(_.id % 2 == 0)) | |
} |
filterメソッドのようにメソッドに渡す関数が引数をひとつしか受けない関数を前提としている場合、プレースホルダを2回利用することはできません。
下記のサンプルはコンパイルエラーになります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val list3 = (1, 2) :: (3, 4) :: (5, 6) :: (7, 8) ::Nil | |
println(list3.filter((_._1 * _._2) % 3 == 0)) |
このような場合は、必ず
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val list3 = (1, 2) :: (3, 4) :: (5, 6) :: (7, 8) ::Nil | |
println(list3.filter(p => ((p._1 * p._2) % 3 == 0))) |
という書き方をしなければなりません。
メソッドに渡す関数が引数を2つ受け取る場合、プレースホルダを2回利用することができます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def sortWith (lt: (A, A) ⇒ Boolean): List[A] |
これはリストのソートをする関数です。
まずは省略しない形で
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val list = 1 :: 5 :: 10 :: 7 :: 9 :: 8 :: 6 :: 2 :: 3 :: 4 :: Nil | |
println(list.sortWith((a:Int, b:Int) => (a <= b))) |
これをプレースホルダを利用して省略すると
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val list = 1 :: 5 :: 10 :: 7 :: 9 :: 8 :: 6 :: 2 :: 3 :: 4 :: Nil | |
println(list.sortWith(_ <= _)) |
これもListの要素がクラスになっていても利用できます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Something(id:Int, something:String) | |
object Hello extends App { | |
val list = Something(2, "past") :: Something(1, "test") :: Something(3, "future") :: Nil | |
println(list.sortWith(_.id <= _.id)) | |
} |
2つの引数のうち一つがコレクションの要素でないものもあるので、注意が必要です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def foldLeft [B] (z: B)(f: (B, A) ⇒ B): B |
このメソッドを省略しない形で実行すると
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val list = (1 to 10).toList | |
println(list.foldLeft[Int](0)((b:Int, a:Int) => (b + a))) |
となります。
そして、省略すると
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val list = (1 to 10).toList | |
println(list.foldLeft[Int](0)(_ + _)) |
となります。こういった関数の場合、コレクションの要素がクラスになっていると
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Something(id:Int, something:String) | |
object Hello extends App { | |
val list = Something(2, "past") :: Something(1, "test") :: Something(3, "future") :: Nil | |
println(list.foldLeft[Int](0)((b:Int, a:Something) => (b + a.id))) | |
} |
となり、1番目の引数と2番目の引数の型が違っているので、省略するときも注意が必要です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Something(id:Int, something:String) | |
object Hello extends App { | |
val list = Something(2, "past") :: Something(1, "test") :: Something(3, "future") :: Nil | |
println(list.foldLeft(0)(_ + _.id)) | |
} |
APIをみたときは「A = コレクションの要素の型」、「B = その他の型」となると覚えておくと良いです。
最後に外でメソッドを作って、それを渡す場合、引数の型がコレクション要素の型となってい必要があります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def foreach (f: (A) ⇒ Unit): Unit | |
</pre> | |
このような関数は、コンパイルに失敗します。 | |
<pre class="prettyprint linenums">class Profile(n:String) { | |
val name = n; | |
def printName = { | |
println(name) | |
} | |
} | |
object Hello extends App { | |
val list4 = new Profile("Michael") :: new Profile("Jenifer") :: Nil | |
list4.foreach(println(_.name)) // ← ここで失敗!! | |
} |
これは、foreachの関数がコレクションの要素の型を引数として受ける関数をパラメータとしているためです。
このような場合は
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Profile(n:String) { | |
val name = n; | |
def printName = { | |
println(name) | |
} | |
} | |
object Hello extends App { | |
val list4 = new Profile("Michael") :: new Profile("Jenifer") :: Nil | |
list4.foreach(p => println(p.name)) // ← | |
} |
とする必要があります。
0 件のコメント:
コメントを投稿