[AD] Scalaアプリケーションの開発・保守は合同会社ミルクソフトにお任せください
List
から重複した要素を削除する方法をご紹介します。
distinctメソッドを使用する
distinct
メソッドを使用することで、List
内の重複した要素を除いたList
を取得することができます。
以下のコードは、distinct
メソッドの使用例です。
val list = List("orange", "apple", "banana", "grape", "strawberry", "apple") val result = list.distinct result.zipWithIndex.foreach { case (v, i) => println(s"[${i}] : ${v}") }
実行結果は以下のようになります。
[0] : orange [1] : apple [2] : banana [3] : grape [4] : strawberry
ただし、distinct
メソッドで重複を削除することができるのは、==
で同じ値かを判定することができる要素を持つList
です。
例えば、(String, Int)
のタプルを要素に持つList
からタプルの第1要素が重複した要素を削除したい場合、distinct
メソッドを使ってしまうと第1要素だけを取り出して比較するのではなく要素のタプルそのものを比較することになるため、重複とはみなされません。
val list = List(("orange", 50), ("apple", 100), ("orange", 60), ("apple", 90)) val result = list.distinct result.zipWithIndex.foreach { case (v, i) => println(s"[$i] : ${v._1}=${v._2}") }
実行結果は以下のようになります。
[0] : orange=50 [1] : apple=100 [2] : orange=60 [3] : apple=90
distinctByメソッドを使用する
前述のタプルを要素に持つList
から、タプルの第1要素が重複した要素を削除するには、distinctBy
メソッドを使用します。
以下のように、distinctBy
メソッドに「List
内の要素から重複チェックをする値へと変換する関数 f: (A) => B
」を渡します。
これによって、distinctBy
メソッドに対して「要素の何の値をもとに同値比較するべきか」を指示することができます。
以下の例ではタプルからタプルの第1要素に変換する関数を指定しています。
val list = List(("orange", 50), ("apple", 100), ("orange", 60), ("apple", 90)) val result = list.distinctBy(a => a._1) result.zipWithIndex.foreach { case (v, i) => println(s"[$i] : ${v._1}=${v._2}") }
以下のようにタプルの第1要素で重複を除いたList
を取得できます。
[0] : orange=50 [1] : apple=100
foldLeftを使用する
distinctBy
メソッドは、2.13
で追加されたメソッドのため、2.12
以前のバージョンでは使用できません。
その場合は、以下のようにfoldLeft
メソッドを使用して、List
内容重複した要素を取り除きます。
val list = List(("orange", 50), ("apple", 100), ("orange", 60), ("apple", 90)) val result = list.foldLeft(List[(String, Int)]()) {(l, v) => { if(l.exists(e => e._1 == v._1)) l else v :: l }} result.reverse.zipWithIndex.foreach { case (v, i) => println(s"[$i] : ${v._1}=${v._2}") }
以下のように、distinctBy
メソッドを使用した場合と同じ結果になります。
[0] : orange=50 [1] : apple=100
Setを使用する
さらに別の方法として、Set
を使用する方法をご紹介します。
Set
は、要素の重複を許さないコレクションです。
最初にList
のtoSet
メソッドで、List
をSet
に変換します。
その後にSet
のtoList
メソッドでList
に変換することで、重複を除いたList
を取得できます。
val list = List("orange", "apple", "banana", "grape", "strawberry", "apple") val result = list.toSet.toList result.zipWithIndex.foreach { case (v, i) => println(s"[${i}] : ${v}") }
distinct
メソッドを使用した場合と同じように、重複を除いたList
を取得できました。
ただし、Set
内の要素の順番は保証されません。
したがって一旦Set
に変換した以上、この方法で得たList
の持つ要素の順番もまた保証されないことに注意しましょう。
[0] : orange [1] : apple [2] : strawberry [3] : banana [4] : grape