Iterator'larla Çalışma

Nette\Utils\Iterables, iterator'larla çalışmaya yarayan fonksiyonlar içeren statik bir sınıftır. Diziler için karşılığı Nette\Utils\Arrays sınıfıdır.

Kurulum:

composer require nette/utils

Tüm örnekler, aşağıdaki takma adın oluşturulduğunu varsayar:

use Nette\Utils\Iterables;

contains (iterable $iterable, $value)bool

Bir iterator içinde verilen değeri arar. Eşleşmeyi denetlerken katı karşılaştırma (===) kullanır. Değer bulunursa true, aksi hâlde false döndürür.

Iterables::contains(new ArrayIterator([1, 2, 3]), 1);    // true
Iterables::contains(new ArrayIterator([1, 2, 3]), '1');  // false

Bu metot, tüm öğeleri elle dolaşmadan belirli bir değerin iterator'da bulunup bulunmadığını hızlıca belirlemeniz gerektiğinde işe yarar.

containsKey (iterable $iterable, $key)bool

Bir iterator içinde verilen anahtarı arar. Eşleşmeyi denetlerken katı karşılaştırma (===) kullanır. Anahtar bulunursa true, aksi hâlde false döndürür.

Iterables::containsKey(new ArrayIterator([1, 2, 3]), 0);  // true
Iterables::containsKey(new ArrayIterator([1, 2, 3]), 4);  // false

every (iterable $iterable, callable $predicate)bool

Iterator'ın tüm öğelerinin $predicate ile tanımlanan koşulu sağlayıp sağlamadığını denetler. $predicate callback'inin imzası function ($value, $key, iterable $iterable): bool şeklindedir ve every() metodunun true döndürmesi için her öğede true döndürmelidir.

$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isBelowThreshold = fn($value) => $value < 40;
$res = Iterables::every($iterator, $isBelowThreshold); // true

Bu metot, bir koleksiyondaki tüm öğelerin belirli bir koşulu karşıladığını doğrulamak için kullanışlıdır; örneğin tüm sayıların belirli bir değerden küçük olup olmadığını.

filter (iterable $iterable, callable $predicate): Generator

Özgün iterator'dan yalnızca $predicate ile tanımlanan koşulu sağlayan öğeleri içeren yeni bir iterator oluşturur. $predicate callback'inin imzası function ($value, $key, iterable $iterable): bool şeklindedir ve korunması gereken öğeler için true döndürmelidir.

$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::filter($iterator, fn($v) => $v < 3);
// 1, 2

Metot bir generator kullanır; yani filtreleme, sonucu dolaştıkça adım adım gerçekleşir. Bu bellek açısından verimlidir ve çok büyük koleksiyonların işlenmesine olanak tanır. Ortaya çıkan iterator'ın tüm öğelerini dolaşmazsanız, özgün iterator'ın tüm öğeleri işlenmediği için hesaplama gücünden tasarruf edersiniz.

first (iterable $iterable, ?callable $predicate=null, ?callable $else=null)mixed

Iterator'ın ilk öğesini döndürür. $predicate verilmişse, koşulu sağlayan ilk öğeyi döndürür. $predicate callback'inin imzası function ($value, $key, iterable $iterable): bool şeklindedir. Uyan bir öğe bulunmazsa (verilmişse) $else callback'i çağrılır ve sonucu döndürülür. $else verilmemişse null döndürülür.

Iterables::first(new ArrayIterator([1, 2, 3]));                   // 1
Iterables::first(new ArrayIterator([1, 2, 3]), fn($v) => $v > 2); // 3
Iterables::first(new ArrayIterator([]));                          // null
Iterables::first(new ArrayIterator([]), else: fn() => false);     // false

Bu metot, koleksiyonun tamamını elle dolaşmadan ilk öğesini ya da belirli bir koşulu sağlayan ilk öğesini hızlıca almanız gerektiğinde işe yarar.

firstKey (iterable $iterable, ?callable $predicate=null, ?callable $else=null)mixed

Iterator'ın ilk öğesinin anahtarını döndürür. $predicate verilmişse, koşulu sağlayan ilk öğenin anahtarını döndürür. $predicate callback'inin imzası function ($value, $key, iterable $iterable): bool şeklindedir. Uyan bir öğe bulunmazsa (verilmişse) $else callback'i çağrılır ve sonucu döndürülür. $else verilmemişse null döndürülür.

Iterables::firstKey(new ArrayIterator([1, 2, 3]));                   // 0
Iterables::firstKey(new ArrayIterator([1, 2, 3]), fn($v) => $v > 2); // 2
Iterables::firstKey(new ArrayIterator(['a' => 1, 'b' => 2]));        // 'a'
Iterables::firstKey(new ArrayIterator([]));                          // null

map (iterable $iterable, callable $transformer): Generator

Özgün iterator'ın her öğesine $transformer callback'ini uygulayarak yeni bir iterator oluşturur. $transformer callback'inin imzası function ($value, $key, iterable $iterable): mixed şeklindedir ve döndürdüğü değer öğenin yeni değeri olarak kullanılır.

$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::map($iterator, fn($v) => $v * 2);
// 2, 4, 6

Metot bir generator kullanır; yani dönüşüm, sonucu dolaştıkça adım adım gerçekleşir. Bu bellek açısından verimlidir ve çok büyük koleksiyonların işlenmesine olanak tanır. Ortaya çıkan iterator'ın tüm öğelerini dolaşmazsanız, özgün iterator'ın tüm öğeleri işlenmediği için hesaplama gücünden tasarruf edersiniz.

mapWithKeys (iterable $iterable, callable $transformer): Generator

Özgün iterator'ın değerlerini ve anahtarlarını dönüştürerek yeni bir iterator oluşturur. $transformer callback'inin imzası function ($value, $key, iterable $iterable): ?array{$newKey, $newValue} şeklindedir. $transformer null döndürürse öğe atlanır. Korunan öğelerde, döndürülen dizinin ilk öğesi yeni anahtar, ikinci öğesi yeni değer olarak kullanılır.

$iterator = new ArrayIterator(['a' => 1, 'b' => 2]);
$iterator = Iterables::mapWithKeys($iterator, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']

map() gibi bu metot da adım adım işleme ve bellek verimliliği için bir generator kullanır. Böylece büyük koleksiyonlarla çalışabilir ve sonucu yalnızca kısmen dolaştığınızda hesaplama gücünden tasarruf edebilirsiniz.

memoize (iterable $iterable): IteratorAggregate

Bir iterator'ın çevresine, dolaşma sırasında anahtarlarını ve değerlerini önbelleğe alan bir sargı oluşturur. Bu, özgün veri kaynağını yeniden dolaşmaya gerek kalmadan veriler üzerinde tekrar tekrar yineleme yapmayı sağlar.

$iterator = /* ... */; // birden çok kez dolaşılamayan veriler
$memoized = Iterables::memoize($iterator);
// Artık $memoized'i veri kaybı olmadan birden çok kez dolaşabilirsiniz

Bu metot, aynı veri kümesini birden çok kez dolaşmanız gereken ama özgün iterator'ın tekrar dolaşmaya izin vermediği ya da yeniden dolaşmanın maliyetli olduğu (örneğin verinin veritabanından veya dosyadan okunduğu) durumlarda işe yarar.

repeatable (callable $factory): IteratorAggregate

Normalde bunu desteklemeyen nesnelerin, tipik olarak PHP generator'larının tekrar tekrar dolaşılmasını sağlar. repeatable() metodu bu sorunu şık bir şekilde çözer: iterator'ın kendisini aktarmak yerine, onu oluşturan bir fonksiyon aktarırsınız. Bu factory, her yineleme döngüsünde otomatik olarak çağrılır.

// İki kez dolaşılamayan standart bir generator
$generator = function () {
	yield 'A';
	yield 'B';
};

$iterator = Iterables::repeatable($generator);

foreach ($iterator as $v) echo $v; // Yazdırır: AB
foreach ($iterator as $v) echo $v; // Yazdırır: AB (generator yeniden çalıştı)

Bu metot, büyük miktarda veriyle çalıştığınız durumlarda memoize() yerine kullanılabilecek bir seçenektir; çünkü repeatable() veriyi önbelleğe almaz, her yinelemede yeniden üretir.

some (iterable $iterable, callable $predicate)bool

Iterator'ın en az bir öğesinin $predicate ile tanımlanan koşulu sağlayıp sağlamadığını denetler. $predicate callback'inin imzası function ($value, $key, iterable $iterable): bool şeklindedir ve some() metodunun true döndürmesi için en az bir öğede true döndürmelidir.

$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isEven = fn($value) => $value % 2 === 0;
$res = Iterables::some($iterator, $isEven); // true

Bu metot, bir koleksiyondaki en az bir öğenin belirli bir koşulu karşıladığını hızlıca doğrulamak için kullanışlıdır; örneğin koleksiyonun en az bir çift sayı içerip içermediğini.

Bkz. every().

toIterator (iterable $iterable): Iterator

Herhangi bir iterable nesneyi (dizi, Traversable) bir Iterator'a dönüştürür. Girdi zaten bir Iterator ise değiştirilmeden döndürülür.

$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// Artık dizi yerine bir Iterator'ınız var

Bu metot, girdi veri türünden bağımsız olarak elinizde bir Iterator bulunduğundan emin olmanız gerektiğinde işe yarar. Çeşitli iterable veri türleriyle çalışan fonksiyonlar yazarken yardımcı olabilir.

versiyon: 4.x