イテレータの操作
Nette\Utils\Iterables は、イテレータを操作するための関数を持つ静的クラスです。配列に対するその類似物は Nette\Utils\Arrays です。
インストール:
composer require nette/utils
すべての例は、エイリアスが作成されていることを前提としています:
use Nette\Utils\Iterables;
contains (iterable $iterable, $value): bool
イテレータ内で指定された値を検索します。一致を確認するために厳密な比較 (===
)
を使用します。値が見つかった場合は true
を、それ以外の場合は
false
を返します。
Iterables::contains(new ArrayIterator([1, 2, 3]), 1); // true
Iterables::contains(new ArrayIterator([1, 2, 3]), '1'); // false
このメソッドは、すべての要素を手動で走査することなく、特定の価値がイテレータ内に存在するかどうかを迅速に判断する必要がある場合に便利です。
containsKey (iterable $iterable, $key): bool
イテレータ内で指定されたキーを検索します。一致を確認するために厳密な比較 (===
)
を使用します。キーが見つかった場合は true
を、それ以外の場合は
false
を返します。
Iterables::containsKey(new ArrayIterator([1, 2, 3]), 0); // true
Iterables::containsKey(new ArrayIterator([1, 2, 3]), 4); // false
every (iterable $iterable, callable $predicate): bool
イテレータのすべての要素が $predicate
で定義された条件を満たすかどうかを検証します。関数 $predicate
は
function ($value, $key, iterable $iterable): bool
のシグネチャを持ち、every()
メソッドが
true
を返すためには、各要素に対して true
を返す必要があります。
$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isBelowThreshold = fn($value) => $value < 40;
$res = Iterables::every($iterator, $isBelowThreshold); // true
このメソッドは、コレクション内のすべての要素が特定の条件を満たしているかどうか(例えば、すべての数値が特定の価値未満であるかどうか)を検証するのに便利です。
filter (iterable $iterable, callable $predicate): Generator
元のイテレータから $predicate
で定義された条件を満たす要素のみを含む新しいイテレータを作成します。関数
$predicate
は function ($value, $key, iterable $iterable): bool
のシグネチャを持ち、保持されるべき要素に対して true
を返す必要があります。
$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::filter($iterator, fn($v) => $v < 3);
// 1, 2
このメソッドはジェネレータを使用します。これは、フィルタリングが結果を走査する際に段階的に行われることを意味します。これはメモリ効率が高く、非常に大きなコレクションの処理も可能です。結果のイテレータのすべての要素を走査しない場合、元のイテレータのすべての要素が処理されないため、計算能力を節約できます。
first (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
イテレータの最初の要素を返します。$predicate
が指定されている場合、指定された条件を満たす最初の要素を返します。関数 $predicate
は function ($value, $key, iterable $iterable): bool
のシグネチャを持ちます。適合する要素が見つからない場合、$else
関数が(指定されていれば)呼び出され、その結果が返されます。$else
が指定されていない場合は null
が返されます。
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
このメソッドは、コレクション全体を手動で走査することなく、コレクションの最初の要素または特定の条件を満たす最初の要素を迅速に取得する必要がある場合に便利です。
firstKey (iterable $iterable, ?callable $predicate=null, ?callable $else=null): mixed
イテレータの最初の要素のキーを返します。$predicate
が指定されている場合、指定された条件を満たす最初の要素のキーを返します。関数
$predicate
は function ($value, $key, iterable $iterable): bool
のシグネチャを持ちます。適合する要素が見つからない場合、$else
関数が(指定されていれば)呼び出され、その結果が返されます。$else
が指定されていない場合は null
が返されます。
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
元のイテレータの各要素に関数 $transformer
を適用して新しいイテレータを作成します。関数 $transformer
は
function ($value, $key, iterable $iterable): mixed
のシグネチャを持ち、その戻り値が要素の新しい値として使用されます。
$iterator = new ArrayIterator([1, 2, 3]);
$iterator = Iterables::map($iterator, fn($v) => $v * 2);
// 2, 4, 6
このメソッドはジェネレータを使用します。これは、変換が結果を走査する際に段階的に行われることを意味します。これはメモリ効率が高く、非常に大きなコレクションの処理も可能です。結果のイテレータのすべての要素を走査しない場合、元のイテレータのすべての要素が処理されないため、計算能力を節約できます。
mapWithKeys (iterable $iterable, callable $transformer): Generator
元のイテレータの値とキーを変換して新しいイテレータを作成します。関数
$transformer
は function ($value, $key, iterable $iterable): ?array{$newKey, $newValue}
のシグネチャを持ちます。$transformer
が null
を返した場合、要素はスキップされます。保持される要素については、返された配列の最初の要素が新しいキーとして、2番目の要素が新しい値として使用されます。
$iterator = new ArrayIterator(['a' => 1, 'b' => 2]);
$iterator = Iterables::mapWithKeys($iterator, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
map()
と同様に、このメソッドは段階的な処理と効率的なメモリ使用のためにジェネレータを利用します。これにより、大きなコレクションを扱い、結果の部分的な走査時に計算能力を節約できます。
memoize (iterable $iterable): IteratorAggregate
イテレーション中にキーと値をキャッシュに保存するイテレータのラッパーを作成します。これにより、元のデータソースを再度走査することなく、データを繰り返しイテレートできます。
$iterator = /* 複数回イテレートできないデータ */
$memoized = Iterables::memoize($iterator);
// これで、$memoized をデータ損失なしで複数回イテレートできます
このメソッドは、同じデータセットを複数回走査する必要があるが、元のイテレータが繰り返しイテレーションを許可しない、または繰り返しの走査が高コストになる(例:データベースやファイルからのデータ読み取り時)場合に便利です。
some (iterable $iterable, callable $predicate): bool
イテレータの少なくとも1つの要素が $predicate
で定義された条件を満たすかどうかを検証します。関数 $predicate
は
function ($value, $key, iterable $iterable): bool
のシグネチャを持ち、some()
メソッドが
true
を返すためには、少なくとも1つの要素に対して true
を返す必要があります。
$iterator = new ArrayIterator([1, 30, 39, 29, 10, 13]);
$isEven = fn($value) => $value % 2 === 0;
$res = Iterables::some($iterator, $isEven); // true
このメソッドは、コレクション内に特定の条件を満たす要素が少なくとも1つ存在するかどうか(例えば、コレクションに少なくとも1つの偶数が含まれているかどうか)を迅速に検証するのに便利です。
every() を参照してください。
toIterator (iterable $iterable): Iterator
任意のイテラブルオブジェクト(array、Traversable)をIteratorに変換します。入力が既にIteratorである場合は、変更せずに返します。
$array = [1, 2, 3];
$iterator = Iterables::toIterator($array);
// これで、配列の代わりにIteratorが得られます
このメソッドは、入力データのタイプに関係なく、Iteratorが利用可能であることを保証する必要がある場合に便利です。これは、さまざまなタイプのイテラブルデータを扱う関数を作成する際に役立ちます。