イテレータ ツール (略してitertoolsは、配列、イテレータ、文字列などのデータのシーケンスを処理するための便利なツールのコレクションです。一部の名前付けと API は Python itertoolsに基づいています。
例
一般的な操作は次のとおりです。
map
とmapBy
filter
、 difference
sorted
groupBy
accumulate
、 collapse
、およびreduce
Twig 経由で利用可能なitertoolsフィルター/関数を使用するには、このサービス定義をconfig/services.yaml
に追加するだけです。
Zicht itertools twigExtension :
tags : ['twig.extension']
composer test
composer lint
以下の例では、次のデータを使用して、さまざまなイテレーター ツールがどのように機能するかを示します。
$ words = [ ' Useful ' , ' Goonies ' , ' oven ' , ' Bland ' , ' notorious ' ];
$ numbers = [ 1 , 3 , 2 , 5 , 4 ];
$ vehicles = [
[
' id ' => 1 ,
' type ' => ' car ' ,
' wheels ' => 4 ,
' colors ' => [ ' red ' , ' green ' , ' blue ' ],
' is_cool ' => false ,
' price ' => 20000 ,
],
[
' id ' => 2 ,
' type ' => ' bike ' ,
' wheels ' => 2 ,
' colors ' => [ ' red ' , ' green ' , ' blue ' ],
' is_cool ' => false ,
' price ' => 600 ,
],
[
' id ' => 5 ,
' type ' => ' unicicle ' ,
' wheels ' => 1 ,
' colors ' => [ ' red ' ],
' is_cool ' => true ,
' price ' => 150 ,
],
[
' id ' => 9 ,
' type ' => ' car ' ,
' wheels ' => 8 ,
' colors ' => [ ' blue ' ],
' is_cool ' => true ,
' price ' => 100000 ,
],
];
上記のデータ例では、 itertools使用して車の固有の色をすべてアルファベット順に取得する方法を示します。
use Zicht itertools util Filters ;
use function Zicht itertools iterable ;
$ vehicles = iterable ( $ vehicles )
-> filter (Filters:: equals ( ' car ' , ' type ' )) // {[vehicle...], [vehicle...]}
-> map ( ' colors ' ) // {0: ['red', 'green', 'blue'], 1: ['blue']}
-> collapse () // {0: 'red', 1: 'green', 2: 'blue', 3: 'blue'}
-> unique () // {0: 'red', 1: 'green', 2: 'blue'}
-> sorted (); // {2: 'blue', 1: 'green', 0: 'red'}
Twig でも同じことを実現できます。
{% for vehicle_color in vehicles
|it. filter ( it . filters . equals ( ' car ' , ' type ' ))
|it. map ( ' colors ' )
|it. collapse
|it. unique
|it. sorted
%}
{{ vehicle_color }}
{% endfor %}
多くのitertoolsは$strategy
パラメータを渡すことができます。このパラメーターは、コレクション内の要素から値を取得するために使用されます。 $strategy
次の 3 つのうちの 1 つです。
null。この場合、要素自体が返されます。例えば:
use function Zicht itertools iterable ;
$ result = iterable ( $ words )-> map ( null );
var_dump ( $ result );
// {0: 'Useful', 1: 'Goonies', 2: 'oven', 3: 'Bland', 4: 'notorious'}
または小枝で:
{{ dump ( word |it. map ) }}
クロージャ。この場合、クロージャは戻り値の計算に使用されるパラメータとして要素の値とキーを使用して呼び出されます。例えば:
use function Zicht itertools iterable ;
$ getDouble = fn ( $ value , $ key ) => 2 * $ value ;
$ result = iterable ( $ numbers )-> map ( $ getDouble );
var_dump ( $ result );
// {0: 2, 1: 6, 2: 4, 3: 10, 4: 8}
または小枝で:
{{ dump ( numbers |it. map ( num => 2 * num )) }}
文字列。この場合、この文字列は、パブリック プロパティ、メソッド、または配列インデックスを検索するクロージャの作成に使用されます。例えば:
use function Zicht itertools iterable ;
$ result = iterable ( $ vehicles )-> map ( ' type ' );
var_dump ( $ result );
// {0: 'car', 1: 'bike', 2: 'unicicle', 3: 'car'}
または小枝で:
{{ dump ( word |it. map ) }}
文字列はドットで区切られた複数の単語で構成され、ネストされたプロパティ、メソッド、配列インデックスにアクセスできます。
文字列内の単語の 1 つが既存のプロパティ、メソッド、または配列インデックスに解決できない場合は、値null
が返されます。例えば:
use function Zicht itertools iterable ;
$ result = iterable ( $ vehicles )-> map ( ' colors.2 ' );
var_dump ( $ result );
// {0: 'blue', 1: 'blue', 2: null, 3: null}
または小枝で:
{{ dump ( vehicles |it. map ( ' colors.2 ' )) }}
Iterator ツールを使用する 1 つの方法は、配列、Iterator、文字列などをIterableIterator
に変換することです。このクラスは、すべての一般的な操作に対する流暢なインターフェイスを提供します。例えば:
use function Zicht itertools iterable ;
$ result = iterable ( $ vehicles )-> filter ( ' is_cool ' )-> mapBy ( ' id ' )-> map ( ' type ' );
var_dump ( $ result );
// {5: 'unicicle', 9: 'car'}
または小枝で:
{{ dump ( vehicles |it. filter ( ' is_cool ' ).mapBy( ' id ' ).map( ' type ' )) }}
マッピングは、あるコレクションを同じ長さの別のコレクションに変換します。 map
使用すると要素を操作でき、 mapBy
使用するとコレクション キーを操作できます。
たとえば、クロージャを使用して$vehicles
の各要素のタイトルを作成できます。
use function Zicht itertools iterable ;
$ getTitle = fn ( $ value , $ key ) => sprintf ( ' %s with %s wheels ' , $ value [ ' type ' ], $ value [ ' wheels ' ]);
$ titles = iterable ( $ vehicles )-> map ( $ getTitle );
var_dump ( $ titles );
// {0: 'car with 4 wheels', ..., 3: 'car with 8 wheels'}
文字列ゲッター戦略を使用すると、車両識別子によってマップされた$vehicles
の各要素のタイプを簡単に取得できます。例えば:
use function Zicht itertools iterable ;
$ types = iterable ( $ vehicles )-> mapBy ( ' id ' )-> map ( ' type ' );
var_dump ( $ types );
// {1: 'car', 2: 'bike', 5: 'unicicle', 9: 'car'}
または小枝で:
{{ dump ( vehicles |it. mapBy ( ' id ' ).map( ' type ' )) }}
mappings.php では、いくつかの一般的なマッピング クロージャが利用可能です。これらの関数を呼び出すと、 map
およびmapBy
に渡すことができるクロージャが返されます。例えば:
use Zicht itertools util Mappings ;
use function Zicht itertools iterable ;
$ lengths = iterable ( $ words )-> map (Mappings:: length ());
var_dump ( $ lengths );
// {0: 6, 1: 3, 2: 4, 3: 5, 4: 9}
または小枝で:
{{ dump ( words |it. map ( it . mappings . length )) }}
フィルタリングは、1 つのコレクションを別の (場合によってはより短い) コレクションに変換します。 filter
使用すると、コレクション内の各要素が評価され、 empty
とみなされる要素は拒否されますが、 empty
はない要素はフィルターを通過できます。
たとえば、クロージャを使用して要素が高価かどうかを判断すると、 filter
高価な要素のみを通過させます。
use function Zicht itertools iterable ;
$ isExpensive = fn ( $ value , $ key ) => $ value [ ' price ' ] >= 10000 ;
$ expensiveTypes = iterable ( $ vehicles )-> filter ( $ isExpensive )-> map ( ' type ' );
var_dump ( $ expensiveTypes );
// {1: 'car', 9: 'car'}
または小枝で:
{{ dump ( vehicles |it. filter ( vehicle => vehicle . price >= 10000 ).map( ' type ' )) }}
文字列ゲッター戦略を使用すると、クールであると考えられる$vehicles
のみを取得できます。例えば:
use function Zicht itertools iterable ;
$ coolVehicleTypes = iterable ( $ vehicles )-> filter ( ' is_cool ' )-> map ( ' type ' );
var_dump ( $ coolVehicleTypes );
// {5: 'unicicle', 9: 'car'}
または小枝で:
{{ dump ( vehicles |it. filter ( ' is_cool ' ).map( ' type ' )) }}
filters.php では、いくつかの一般的なフィルター クロージャが利用可能です。これらの関数を呼び出すと、 filter
に渡すことができるクロージャが返されます。例えば:
use Zicht itertools util Filters ;
use function Zicht itertools iterable ;
$ movieWords = iterable ( $ words )-> filter (Filters:: in ([ ' Shining ' , ' My little pony ' , ' Goonies ' ]));
var_dump ( $ movieWords );
// {1: 'Goonies'}
または小枝で:
{{ dump ( words |it. filter ( it . filters . in ([ ' Shining ' , " My little pony', 'Goonies'])) }}
sorted
あるコレクションを同じサイズの別のコレクションに変換しますが、要素の順序が変更される可能性があります。
たとえば、デフォルトのnull
ゲッター戦略を使用して、要素値を使用して昇順に並べ替えます。
use function Zicht itertools iterable ;
$ ordered = iterable ( $ numbers )-> sorted ();
var_dump ( $ ordered );
// {0: 1, 2: 2, 1: 3, 4: 4, 3: 5}
または小枝で:
{{ dump ( numbers |it. sorted }}
ソート アルゴリズムはキーを保持し、安定性が保証されます。つまり、要素が同じ値を使用して並べ替えられる場合、並べ替えられた順序は入力要素の順序と同じであることが保証されます。これは、標準の PHP ソート関数とは異なります。
クロージャゲッター戦略を使用すると、戻り値を使用して順序が決定されます。クロージャは要素ごとに 1 回だけ呼び出され、結果の値は比較可能である必要があります。例えば:
use function Zicht itertools iterable ;
$ getLower = fn ( $ value , $ key ) => strtolower ( $ value );
$ ordered = iterable ( $ words )-> sorted ( $ getLower );
var_dump ( $ ordered );
// {3: 'Bland', 1: 'Goonies', 2: 'oven', 0: 'Useful', 4: 'notorious'};
Mappings.php は、乱数を返すマッピング クロージャを提供します。これを使用して、コレクションをランダムな順序で並べ替えることができます。例えば:
use Zicht itertools util Mappings ;
use function Zicht itertools iterable ;
$ randomized = iterable ( $ words )-> sorted (Mappings:: random ());
var_dump ( $ randomized );
// {... randomly ordere words ...}
または小枝で:
{{ dump ( words |it. sorted ( it . mappings . random )) }}
groupBy
1 つのコレクションを、特定の基準に基づいて要素をグループ化する 1 つ以上のコレクションに変換します。
たとえば、文字列ゲッター戦略を使用すると、同じタイプのすべての$vehicles
グループ化できます。
use function Zicht itertools iterable ;
$ vehiclesByType = iterable ( $ vehicles )-> groupBy ( ' type ' );
var_dump ( $ vehiclesByType );
// {'bike': {1: [...]}, 'car': {0: [...], 3: [...]} 'unicicle': {2: [...]}}
または小枝で:
{{ dump ( vehicles |it. groupBy ( ' type ' )) }}
車両の元のキーが依然として結果のグループの一部であるというわけではなく、各グループ内の要素は入力での順序を維持します。つまり、 sorted
によって提供される安定した並べ替えが使用されます。
reduce
2 つの引数のクロージャをコレクション内の要素に対して左から右に累積的に呼び出すことにより、コレクションを単一の値に変換します。
たとえば、引数を指定しないと、 reduce
コレクションのすべての要素をまとめて追加します。
use function Zicht itertools iterable ;
$ sum = iterable ( $ numbers )-> reduce ();
var_dump ( $ sum );
// 15
または小枝で:
{{ dump ( numbers |it. reduce ) }}
上記の例では、使用されるデフォルトのクロージャは次のようになります。
public static function add ( $ a , $ b ): Closure
{
return $ a + $ b ;
}
$numbers
要素 {1, 3, 2, 5, 4} で構成されているとすると、 add
クロージャが 4 回呼び出されます。
$ sum = Reductions:: add (Reductions:: add (Reductions:: add (Reductions:: add (( 1 , 3 ), 2 ), 5 ), 4 ));
var_dump ( $ sum );
// 15
ductions.php では、いくつかの一般的なリダクション クロージャが利用可能です。これらの関数を呼び出すと、 reduction
に渡すことができるクロージャが返されます。例えば:
use Zicht itertools util Reductions ;
use function Zicht itertools iterable ;
$ scentence = iterable ( $ words )-> reduce (Reductions:: join ( ' - ' ));
var_dump ( $ scentence );
// 'Useful - Goonies - oven - Bland - notorious'
または小枝で:
{{ dump ( words |it. reduce ( it . reductions . join ( ' - ' )) }}
もう 1 つの一般的な削減は、複数のリストを 1 つのリストに連鎖させることです。このプロセスを崩壊と呼びます。このプロセスは、 reduce
とchain
一緒に使用して実現することもできますが、頻繁に使用されるため、 collapse
ヘルパーを使用すると使用が簡単になります。次に例を示します。
use function Zicht itertools iterable ;
$ flat = iterable ([[ ' one ' , ' two ' ], [ ' three ' ]])-> collapse ();
var_dump ( $ flat );
// {0: 'one', 1: 'two', 0: 'three'}
または小枝で:
{% set data = [[ ' one ' , ' two ' ], [ ' three ' ]] %}
{{ dump ( data |it. collapse ) }}