フィルタ(高階関数)
関数型プログラミングにおいて、フィルタは、データ構造(通常はリスト)を何らかの順序で処理し、指定された述語がブール値を返す元のデータ構造の要素を正確に含む新しいデータ構造を生成する高階関数です。 true
例
Haskellでは、コード例
フィルター偶数[ 1 .. 10 ] は、整数1、2 、…、10のリストの各要素に述語をevenこの順序で適用し、述語がブール値trueを返す要素の新しいリストを作成することで、リスト2、4、…、10を評価します。これにより、リストの偶数要素のみを含むリストが得られます。逆に、コード例
フィルター(ない.偶数) [ 1 .. 10 ] evenは、述語がブール値 false を返す整数 1、2、…、10 のリストの要素を収集して、リスト 1、3、…、9 に評価されます( は関数合成演算子.です)。
視覚的な例
X = [0, 5, 8, 3, 2, 1]以下に、関数に応じた整数のリストのフィルター処理の各ステップのビューを示します。
この関数は、 が偶数の場合、戻り値は、そうでない場合は であることを表します。これが述語です。

言語の比較
FilterはHaskell、[1] OCaml、[2] Standard ML、[3] Erlangなど多くのプログラミング言語の標準関数です。[4] Common Lispは関数とを提供します。[5] Scheme Requests forImplementation (SRFI) 1は、言語Scheme用のfilterの実装を提供します。[6] C++はアルゴリズム(mutating)と(non-mutating)を提供し、 C++11はさらに(non-mutating)を提供します。[7] Smalltalkはコレクション用のメソッドを提供します。Filterは、リスト内包表記をサポートする言語ではリスト内包表記を使用して実現することもできます。remove-ifremove-if-not remove_ifremove_copy_ifcopy_if select:
Haskell ではfilter次のように実装できます。
フィルター:: ( a -> Bool ) -> [ a ] -> [ a ]フィルター_ [] = []フィルターp ( x : xs ) = [ x | p x ] ++フィルターp xs ここで、[]は空のリスト、++はリストの連結演算を表し、 は条件が成り立つ場合( と評価される場合) 、条件[x | p x]付きで値 を保持するリストを表します。xp xTrue
| 言語 | フィルター | 注記 |
|---|---|---|
| APL | (pred array)/arrayまたは pred | 2 番目の例は APL dop です。 |
| C# 3.0 | ienum.Where(pred)または where句 | 拡張メソッド ienumはIEnumerableです。 同様に、すべての.NET言語で |
| CFML | obj.filter(func) | objは配列または構造体です。各func要素の値は引数として受け取ります。 |
| クロージュア | (filter predicate list)[8] | または、リストの内包表記を使って:(for [x list :when (pred x)] x) |
| コモンリスプ | (remove-if inverted-pred list) | この関数はremove-if-not非推奨となりました[5] 。代わりに、remove-if述語が補語となる同等の関数が採用されました[9]。したがって、フィルタは次のように記述されるか、より簡潔に記述されます。ここで、はの反転した値を返します。[10](remove-if-not #'oddp '(0 1 2 3))(remove-if (complement #'oddp) '(0 1 2 3))(remove-if #'evenp '(0 1 2 3))evenpoddp |
| C++ | std::remove_copy_if(begin, end, result, prednot) | ヘッダー<algorithm>の begin、end、resultは反復子であり 、述語は逆になっている |
| D | std.algorithm.filter!(pred)(list) | |
| アーラン | lists:filter(Fun, List) | または、リストの内包表記を使って:[ X || X <- List, Fun(X) ] |
| グルーヴィー | list.findAll(pred) | |
| ハスケル | filter pred list | または、リストの内包表記を使って:[x | x <- list, pred x] |
| ハックス | list.filter(pred)Lambda.filter(list, pred) | または、リストの内包表記を使って:[x | x <- list, pred x] |
| J | (#~ pred) list | モナドフックの例。# はコピー、~ は引数を反転します。(f g) y = y f (g y) |
| ジュリア | filter(pred, array) | フィルター関数はdictデータ型も受け入れます。あるいは、リスト内包表記を使って次のように記述することもできます。[x for x in array if pred(x)] |
| Java 8以降 | stream.filter(pred) | |
| JavaScript 1.6 | array.filter(pred) | |
| コトリン | array.filter(pred) | |
| マセマティカ | Select[list, pred] | |
| Objective-C ( Mac OS X 10.4 以降ではCocoa ) | [array filteredArrayUsingPredicate:pred] | predNSPredicateオブジェクトであり、表現力が制限される可能性がある |
| F#、OCaml、標準ML | List.filter pred list | |
| PARI/GP | select(expr, list) | バージョン 2.4.2 では、引数の順序が逆になっています。 |
| パール | grep block list | |
| PHP | array_filter(array, pred) | |
| プロローグ | filter(+Closure,+List,-List) | ISO/IEC 13211-1:1995/Cor.2:2012 [11]以来、コア規格にはcall/N[12]によるクロージャの適用が含まれている。 |
| パイソン | filter(func, list) | あるいは、リスト内包表記を介して:。Python 3では、はリストではなくイテレータを返すように変更されました。 [13]述語が偽である要素のイテレータを返す補完的な機能は、モジュールと同様に標準ライブラリでも利用できます。filterfilterfalseitertools |
| ルビー | enum.find_all {block} | enum列挙体です |
| さび | iterator.filter(pred) | iteratorはIteratorであり、メソッドfilterは新しいイテレータを返します。は、イテレータの項目を受け取り、 を返すpred関数(具体的には )です。FnMutbool |
| S、R | Filter(pred,array) | 2番目のケースでは、predはベクトル化された関数でなければならない。 |
| スカラ | list.filter(pred) | あるいは、for 理解を介して:for(x <- list; if pred) yield x |
| スキームR 6 RS | (filter pred list)(remove inverted pred list)(partition pred list list) | |
| 雑談 | aCollection select: aBlock | |
| 迅速 | array.filter(pred) | |
| XPath、XQuery | list[block]filter(list, func) | blockコンテキスト項目は.現在の値を保持します |
変種
フィルターは元のリストを変更せずに結果を生成します。多くのプログラミング言語では、パフォーマンス向上のためにリスト引数を破壊的に変更するバリアントも提供されています。フィルターの他のバリアント(例えば、Haskell dropWhile[14]およびpartition[15] )も一般的です。純粋関数型プログラミング言語における一般的なメモリ最適化は、入力リストとフィルター結果の最長共通末尾を共有すること(末尾共有)です。
参照
参考文献
- ^ Haskell標準プレリュードのフィルタ
- OCaml標準ライブラリモジュールの^フィルタ
list - ^ 「リスト構造」.標準ML基礎ライブラリ. 2007年9月25日閲覧。
- ^ Erlang STDLIBリファレンスマニュアルのモジュールドキュメントのfilter/2
lists - ^ ab Common Lisp HyperSpec の関数 REMOVE、REMOVE-IF、REMOVE-IF-NOT、DELETE、DELETE-IF、DELETE-IF-NOT
- SRFI 1の^フィルタ
- ^ SGI標準テンプレートライブラリ(STL) 仕様の remove_if と remove_copy_if
- ^ ClojureDocs の clojure.core/filter
- ^ Common Lisp HyperSpecの COMPLEMENT 関数
- ^ Common Lisp HyperSpecの関数 EVENP、ODDP
- ^ ISO/IEC 13211-1:1995/Cor 2:2012
- ^ “技術的正誤表草案 2”.
- ^ 「組み込み関数 — Python 3.9.0 ドキュメント」. docs.python.org . 2020年10月28日閲覧。
- ^ Haskell フィルター dropWhile
- ^ Haskell フィルタパーティション