Listのfilter、filterNotメソッドの使い方

Scala 3 (Dotty 0.26.0-RC1) 2.13.3 2.12.12
最終更新:2020年6月30日

[AD] scalapediaでは記事作成ボランティアを募集しています

Scalaの scala.collection.immutable.List クラスにおいて、キーや値が特定の条件に合致する要素、あるいは合致しない要素のみ抽出する方法についてご紹介します。

概要

キーや値が特定の条件に合致する要素のみ抽出するには、filterメソッドを使用します。 また、合致しない要素のみ抽出するには、filterNotメソッドを使用します。

ただし、この種の処理を行う場合には、for式を使った方がより効率的に処理できることもあります。
この点にだけ注意しましょう。

Listの要素を抽出するには filter メソッドを使用する

さて、それでは以下のListクラスのインスタンスについて見ていきましょう。

val list: List[Int] = List(1, 2, 3, 4)

特定の条件を満たす要素のみをフィルタリングしたい場合は、filterメソッドを使用します。
サンプルコードはこちらです。

list.filter( _ % 2 == 1 ) .foreach(println)

このコードではListに含まれる要素のうち、奇数のみ出力しています。

出力結果は以下のようになります。

1 3

結果として出力された要素がいずれもfilterメソッドの引数に渡した条件式を満たしており、 満たさない要素はすべて排除されていることを確認してください。

Listの要素を除外するには filterNot メソッドを使用する

特定の条件を満たす要素を除外したい場合はfilterNotメソッドを使用します。
サンプルコードはこちらです。

list.filterNot( _ % 2 == 1 ) .foreach(println)

このコードではListに含まれる要素のうち、奇数でない要素、つまり偶数のみ出力しています。

出力結果は以下のようになります。

2 4

結果として出力された要素がいずれもfilterNotメソッドに引数として渡した条件式を満たしておらず、 条件に合致する要素はいずれも含まれていないことを確認してください。

for 式で効率的に抽出する

実は、for式でもfilterあるいはfilterNotメソッド相当の処理を行うことができます。
書き方は、for式の途中にif文を追加するだけでOKです。

for { id <- list if id % 2 == 1 } println(id)

出力結果は以下のようになります。

1 3

for式を使った方が効率的に処理できるので、特別な理由がない限りはfor式を使うようにしましょう。

for式を使った方が効率的になる理由は、 for式の内部実装ではfilterメソッドではなくwithFilterメソッドを活用しているからです。
withFilterメソッドによって中間コレクションを生成することなく次の処理を行うことができるので、効率的に処理できるのです。

これらのメソッドは IterableOnceOps に定義されている

filterfilterNotメソッドは scala.lang.IterableOnceOps に定義されています。

Scala Standard Library:IterableOnceOps#filter
Scala Standard Library:IterableOnceOps#filterNot

したがってfilterfilterNotは、 Listだけでなく scala.collection.mutable.ListBuffer や、scala.collection.Mapscala.collection.Set など、 IterableOnceOps を継承しているクラスにおいても共通に利用することができます。

サイト内検索