Alat Iterator, atau disingkat itertools , adalah kumpulan alat praktis untuk menangani urutan data seperti array, iterator, dan string. Beberapa penamaan dan API didasarkan pada itertools Python.
Contoh
Operasi umum meliputi:
map dan mapByfilter , differencesortedgroupByaccumulate , collapse , dan reduce Untuk menggunakan filter/fungsi itertools yang tersedia melalui Twig, cukup tambahkan definisi layanan ini di config/services.yaml Anda
Zicht itertools twigExtension :
tags : ['twig.extension'] composer testcomposer lint Contoh di bawah ini akan menggunakan data berikut untuk mengilustrasikan cara kerja berbagai alat Iterator:
$ 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 ,
],
];Dengan contoh data di atas, inilah cara Anda menggunakan itertools untuk mendapatkan semua warna unik mobil dalam urutan abjad:
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'}Anda dapat mencapai hal yang sama di 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 %} Banyak itertools yang dapat melewati parameter $strategy . Parameter ini digunakan untuk mendapatkan nilai dari elemen-elemen dalam koleksi. $strategy dapat berupa salah satu dari tiga hal berikut:
null, dalam hal ini elemen itu sendiri dikembalikan. Misalnya:
use function Zicht itertools iterable ;
$ result = iterable ( $ words )-> map ( null );
var_dump ( $ result );
// {0: 'Useful', 1: 'Goonies', 2: 'oven', 3: 'Bland', 4: 'notorious'}Atau di Ranting:
{{ dump ( word |it. map ) }}penutupan, dalam hal ini penutupan dipanggil dengan nilai elemen dan kunci sebagai parameter yang akan digunakan untuk menghitung nilai kembalian. Misalnya:
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}Atau di Ranting:
{{ dump ( numbers |it. map ( num => 2 * num )) }}sebuah string, dalam hal ini string ini digunakan untuk membuat penutupan yang mencoba menemukan properti publik, metode, atau indeks array. Misalnya:
use function Zicht itertools iterable ;
$ result = iterable ( $ vehicles )-> map ( ' type ' );
var_dump ( $ result );
// {0: 'car', 1: 'bike', 2: 'unicicle', 3: 'car'}Atau di Ranting:
{{ dump ( word |it. map ) }}String dapat terdiri dari beberapa kata yang dipisahkan titik, memungkinkan akses ke properti bertingkat, metode, dan indeks array.
Jika salah satu kata dalam string tidak dapat diselesaikan menjadi properti, metode, atau indeks array yang ada, nilai null akan dikembalikan. Misalnya:
use function Zicht itertools iterable ;
$ result = iterable ( $ vehicles )-> map ( ' colors.2 ' );
var_dump ( $ result );
// {0: 'blue', 1: 'blue', 2: null, 3: null}Atau di Ranting:
{{ dump ( vehicles |it. map ( ' colors.2 ' )) }} Salah satu cara menggunakan Alat Iterator adalah dengan mengubah array, Iterator, string, dll menjadi IterableIterator . Kelas ini menyediakan antarmuka yang lancar untuk semua operasi umum. Misalnya:
use function Zicht itertools iterable ;
$ result = iterable ( $ vehicles )-> filter ( ' is_cool ' )-> mapBy ( ' id ' )-> map ( ' type ' );
var_dump ( $ result );
// {5: 'unicicle', 9: 'car'}Atau di Ranting:
{{ dump ( vehicles |it. filter ( ' is_cool ' ).mapBy( ' id ' ).map( ' type ' )) }} Pemetaan mengubah satu koleksi menjadi koleksi lain yang panjangnya sama. Menggunakan map memungkinkan manipulasi elemen sementara mapBy memungkinkan manipulasi kunci koleksi.
Misalnya, kita dapat menggunakan penutupan untuk membuat judul untuk setiap elemen di $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'} Dengan menggunakan strategi pengambil string, kita dapat dengan mudah mendapatkan tipe untuk setiap elemen di $vehicles yang dipetakan oleh pengidentifikasi kendaraan. Misalnya:
use function Zicht itertools iterable ;
$ types = iterable ( $ vehicles )-> mapBy ( ' id ' )-> map ( ' type ' );
var_dump ( $ types );
// {1: 'car', 2: 'bike', 5: 'unicicle', 9: 'car'}Atau di Ranting:
{{ dump ( vehicles |it. mapBy ( ' id ' ).map( ' type ' )) }} Ada beberapa penutupan pemetaan umum yang tersedia di maps.php. Memanggil fungsi-fungsi ini akan mengembalikan penutupan yang dapat diteruskan ke map dan mapBy . Misalnya:
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}Atau di Ranting:
{{ dump ( words |it. map ( it . mappings . length )) }} Pemfilteran mengubah satu koleksi menjadi koleksi lain, mungkin lebih pendek. Dengan menggunakan filter setiap elemen dalam koleksi dievaluasi, elemen yang dianggap empty akan ditolak, sedangkan elemen yang tidak empty akan diizinkan melewati filter.
Misalnya, kita dapat menggunakan penutupan untuk menentukan apakah suatu elemen mahal, filter hanya akan mengizinkan elemen mahal tersebut melewati:
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'}Atau di Ranting:
{{ dump ( vehicles |it. filter ( vehicle => vehicle . price >= 10000 ).map( ' type ' )) }} Dengan menggunakan strategi string getter kita hanya bisa mendapatkan $vehicles yang dianggap keren. Misalnya:
use function Zicht itertools iterable ;
$ coolVehicleTypes = iterable ( $ vehicles )-> filter ( ' is_cool ' )-> map ( ' type ' );
var_dump ( $ coolVehicleTypes );
// {5: 'unicicle', 9: 'car'}Atau di Ranting:
{{ dump ( vehicles |it. filter ( ' is_cool ' ).map( ' type ' )) }} Ada beberapa penutupan filter umum yang tersedia di filter.php. Memanggil fungsi ini akan mengembalikan penutupan yang dapat diteruskan ke filter . Misalnya:
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'}Atau di Ranting:
{{ dump ( words |it. filter ( it . filters . in ([ ' Shining ' , " My little pony', 'Goonies'])) }} sorted mengubah satu koleksi menjadi koleksi lain dengan ukuran yang sama tetapi dengan elemen yang mungkin disusun ulang.
Misalnya, dengan menggunakan strategi pengambil null , yang merupakan default, kita akan mengurutkan menggunakan nilai elemen dalam urutan menaik:
use function Zicht itertools iterable ;
$ ordered = iterable ( $ numbers )-> sorted ();
var_dump ( $ ordered );
// {0: 1, 2: 2, 1: 3, 4: 4, 3: 5}Atau di Ranting:
{{ dump ( numbers |it. sorted }}Algoritme pengurutan akan mempertahankan kunci dan dijamin stabil. Yaitu ketika elemen diurutkan menggunakan nilai yang sama, maka urutan pengurutannya dijamin sama dengan urutan elemen masukan. Ini bertentangan dengan fungsi pengurutan standar PHP.
Dengan menggunakan strategi pengambil penutupan, nilai yang dikembalikan digunakan untuk menentukan pesanan. Penutupan ini dipanggil tepat satu kali per elemen, dan nilai yang dihasilkan harus sebanding. Misalnya:
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'};maps.php menyediakan penutupan pemetaan yang mengembalikan nomor acak. Ini dapat digunakan untuk mengurutkan koleksi dalam urutan acak. Misalnya:
use Zicht itertools util Mappings ;
use function Zicht itertools iterable ;
$ randomized = iterable ( $ words )-> sorted (Mappings:: random ());
var_dump ( $ randomized );
// {... randomly ordere words ...}Atau di Ranting:
{{ dump ( words |it. sorted ( it . mappings . random )) }} groupBy mengonversi satu koleksi menjadi satu atau lebih koleksi yang mengelompokkan elemen berdasarkan kriteria tertentu.
Misalnya, dengan menggunakan strategi pengambil string, kita dapat mengelompokkan semua $vehicles yang bertipe sama menjadi satu:
use function Zicht itertools iterable ;
$ vehiclesByType = iterable ( $ vehicles )-> groupBy ( ' type ' );
var_dump ( $ vehiclesByType );
// {'bike': {1: [...]}, 'car': {0: [...], 3: [...]} 'unicicle': {2: [...]}}Atau di Ranting:
{{ dump ( vehicles |it. groupBy ( ' type ' )) }} Bukan berarti kunci asli dari kendaraan masih menjadi bagian dari grup yang dihasilkan, dan elemen dalam setiap grup menjaga urutan inputnya, yaitu menggunakan penyortiran stabil yang disediakan oleh sorted .
reduce mengubah koleksi menjadi nilai tunggal dengan memanggil penutupan dua argumen secara kumulatif ke elemen dalam koleksi, dari kiri ke kanan.
Misalnya, tanpa argumen apa pun, reduce akan menjumlahkan semua elemen koleksi:
use function Zicht itertools iterable ;
$ sum = iterable ( $ numbers )-> reduce ();
var_dump ( $ sum );
// 15Atau di Ranting:
{{ dump ( numbers |it. reduce ) }}Pada contoh di atas, penutupan default yang digunakan terlihat seperti ini:
public static function add ( $ a , $ b ): Closure
{
return $ a + $ b ;
} Mengingat $numbers terdiri dari elemen {1, 3, 2, 5, 4}, penutupan add dipanggil empat kali:
$ sum = Reductions:: add (Reductions:: add (Reductions:: add (Reductions:: add (( 1 , 3 ), 2 ), 5 ), 4 ));
var_dump ( $ sum );
// 15 Ada beberapa penutupan reduksi umum yang tersedia di reduksi.php. Memanggil fungsi-fungsi ini akan mengembalikan penutupan yang dapat diteruskan ke reduction . Misalnya:
use Zicht itertools util Reductions ;
use function Zicht itertools iterable ;
$ scentence = iterable ( $ words )-> reduce (Reductions:: join ( ' - ' ));
var_dump ( $ scentence );
// 'Useful - Goonies - oven - Bland - notorious'Atau di Ranting:
{{ dump ( words |it. reduce ( it . reductions . join ( ' - ' )) }} Pengurangan umum lainnya adalah merangkai beberapa daftar menjadi satu daftar. Kami menyebut proses ini gagal. Proses ini juga dapat dicapai dengan menggunakan reduce dan chain bersama-sama, namun karena sering digunakan, pembantu collapse membuat penggunaannya lebih mudah, misalnya:
use function Zicht itertools iterable ;
$ flat = iterable ([[ ' one ' , ' two ' ], [ ' three ' ]])-> collapse ();
var_dump ( $ flat );
// {0: 'one', 1: 'two', 0: 'three'}Atau di Ranting:
{% set data = [[ ' one ' , ' two ' ], [ ' three ' ]] %}
{{ dump ( data |it. collapse ) }}