Array-Funktionen
Diese Seite behandelt die Klassen Nette\Utils\Arrays, ArrayHash und ArrayList, die sich um Arrays drehen.
Installation:
composer require nette/utils
Arrays
Nette\Utils\Arrays ist eine statische Klasse mit nützlichen Funktionen für die Arbeit mit Arrays. Ihr Gegenstück für Iteratoren ist Nette\Utils\Iterables.
Die folgenden Beispiele setzen voraus, dass dieser Klassen-Alias definiert ist:
use Nette\Utils\Arrays;
associate (array $array, string|array $path): array|\stdClass
Diese Funktion wandelt das Array $array flexibel in ein assoziatives Array oder in Objekte um, und zwar nach dem
angegebenen Pfad $path. Der Pfad kann ein String oder ein Array sein. Er besteht aus den Namen der Schlüssel im
Eingabe-Array und aus Operatoren wie [], ->, = und |. Ist der Pfad
ungültig, wirft die Funktion eine Nette\InvalidArgumentException.
// Umwandlung in ein assoziatives Array anhand eines einfachen Schlüssels
$arr = [
['name' => 'John', 'age' => 11],
['name' => 'Mary', 'age' => null],
// ...
];
$result = Arrays::associate($arr, 'name');
// $result = ['John' => ['name' => 'John', 'age' => 11], 'Mary' => ['name' => 'Mary', 'age' => null]]
// Zuweisung der Werte eines Schlüssels an einen anderen mit dem Operator =
$result = Arrays::associate($arr, 'name=age'); // oder ['name', '=', 'age']
// $result = ['John' => 11, 'Mary' => null, ...]
// Erzeugung eines Objekts mit dem Operator ->
$result = Arrays::associate($arr, '->name'); // oder ['->', 'name']
// $result = (object) ['John' => ['name' => 'John', 'age' => 11], 'Mary' => ['name' => 'Mary', 'age' => null]]
// Gruppierung auf zwei Ebenen mit dem Operator |
$result = Arrays::associate($arr, 'name|age'); // oder ['name', '|', 'age']
// $result: ['John' => [11 => ['name' => 'John', 'age' => 11]], 'Mary' => ['' => ['name' => 'Mary', 'age' => null]], ...]
// Hinzufügen zu einem Array mit []
$result = Arrays::associate($arr, 'name[]'); // oder ['name', '[]']
// $result: ['John' => [['name' => 'John', 'age' => 11]], 'Mary' => [['name' => 'Mary', 'age' => null]], ...]
contains (array $array, $value): bool
Prüft, ob ein Wert im Array vorhanden ist. Verwendet einen strikten Vergleich (===).
Arrays::contains([1, 2, 3], 1); // true
Arrays::contains(['1', false], 1); // false
every (array $array, callable $predicate): bool
Prüft, ob alle Elemente des Arrays den Test bestehen, den die übergebene Funktion $predicate mit der Signatur
function ($value, $key, array $array): bool umsetzt.
$array = [1, 30, 39, 29, 10, 13];
$isBelowThreshold = fn($value) => $value < 40;
$res = Arrays::every($array, $isBelowThreshold); // true
Siehe some().
filter (array $array, callable $predicate): array
Gibt ein neues Array mit allen Schlüssel-Wert-Paaren zurück, die dem angegebenen $predicate entsprechen. Der
Callback hat die Signatur function ($value, int|string $key, array $array): bool.
Arrays::filter(
['a' => 1, 'b' => 2, 'c' => 3],
fn($v) => $v < 3,
);
// gibt ['a' => 1, 'b' => 2] zurück
first (array $array, ?callable $predicate=null, ?callable $else=null): mixed
Gibt das erste Element zurück (das dem angegebenen Prädikat entspricht, sofern eines angegeben ist). Gibt es kein solches
Element, wird das Ergebnis des Aufrufs von $else oder null zurückgegeben. Das $predicate hat die
Signatur function ($value, int|string $key, array $array): bool.
Anders als reset() verändert die Methode den internen Zeiger nicht. Die Parameter $predicate und
$else gibt es seit Version 4.0.4.
Arrays::first([1, 2, 3]); // 1
Arrays::first([1, 2, 3], fn($v) => $v > 2); // 3
Arrays::first([]); // null
Arrays::first([], else: fn() => false); // false
Siehe last().
firstKey (array $array, ?callable $predicate=null): int|string|null
Gibt den Schlüssel des ersten Elements zurück (das dem angegebenen Prädikat entspricht, sofern eines angegeben ist), oder
null, wenn es kein solches Element gibt. Das $predicate hat die Signatur
function ($value, int|string $key, array $array): bool.
Arrays::firstKey([1, 2, 3]); // 0
Arrays::firstKey([1, 2, 3], fn($v) => $v > 2); // 2
Arrays::firstKey(['a' => 1, 'b' => 2]); // 'a'
Arrays::firstKey([]); // null
Siehe lastKey().
flatten (array $array, bool $preserveKeys=false): array
Flacht ein mehrstufiges Array auf eine einzige Ebene ab. Die Schlüssel lassen sich erhalten, wenn $preserveKeys
auf true gesetzt wird.
$array = Arrays::flatten([1, 2, [3, 4, [5, 6]]]);
// $array = [1, 2, 3, 4, 5, 6];
get (array $array, string|int|array $key, mixed $default=null): mixed
Gibt das Element $array[$key] zurück. Existiert es nicht, wirft die Methode eine
Nette\InvalidArgumentException, es sei denn, im dritten Argument ist ein Standardwert angegeben, der dann
zurückgegeben wird.
// wenn $array['foo'] nicht existiert, wirft es eine Exception
$value = Arrays::get($array, 'foo');
// wenn $array['foo'] nicht existiert, gibt es 'bar' zurück
$value = Arrays::get($array, 'foo', 'bar');
Der $key kann auch ein Array sein, das einen Pfad in ein verschachteltes Array beschreibt.
$array = ['color' => ['favorite' => 'red'], 5];
$value = Arrays::get($array, ['color', 'favorite']);
// gibt 'red' zurück
getRef (array &$array, string|int|array $key): mixed
Holt eine Referenz auf das angegebene Element des Arrays. Existiert das Element nicht, wird es mit dem Wert null angelegt.
$valueRef = & Arrays::getRef($array, 'foo');
// gibt eine Referenz auf $array['foo'] zurück
Funktioniert wie get() auch mit mehrdimensionalen Arrays.
$value = & Arrays::getRef($array, ['color', 'favorite']);
// gibt eine Referenz auf $array['color']['favorite'] zurück
grep (array $array, string $pattern, bool $invert=false): array
Gibt nur die Elemente des Arrays zurück, deren Wert dem regulären Ausdruck $pattern entspricht. Ist
$invert gleich true, werden die Elemente zurückgegeben, die nicht entsprechen. Ein Fehler beim
Kompilieren oder beim Auswerten des Ausdrucks wirft eine Nette\RegexpException.
$filteredArray = Arrays::grep($array, '~^\d+$~');
// gibt nur die Array-Elemente zurück, die aus Ziffern bestehen
insertAfter (array &$array, string|int|null $key, array $inserted): void
Fügt den Inhalt des Arrays $inserted unmittelbar hinter dem Element mit dem Schlüssel $key in das
Array $array ein. Ist $key gleich null (oder existiert er im Array nicht), wird am Ende
eingefügt.
$array = ['first' => 10, 'second' => 20];
Arrays::insertAfter($array, 'first', ['hello' => 'world']);
// $array = ['first' => 10, 'hello' => 'world', 'second' => 20];
insertBefore (array &$array, string|int|null $key, array $inserted): void
Fügt den Inhalt des Arrays $inserted vor dem Element mit dem Schlüssel $key in das Array
$array ein. Ist $key gleich null (oder existiert er im Array nicht), wird am Anfang
eingefügt.
$array = ['first' => 10, 'second' => 20];
Arrays::insertBefore($array, 'first', ['hello' => 'world']);
// $array = ['hello' => 'world', 'first' => 10, 'second' => 20];
invoke (iterable $callbacks, …$args): array
Ruft alle Callbacks in der iterierbaren Struktur auf und gibt ein Array der Ergebnisse zurück.
$callbacks = [
'+' => fn($a, $b) => $a + $b,
'*' => fn($a, $b) => $a * $b,
];
$array = Arrays::invoke($callbacks, 5, 11);
// $array = ['+' => 16, '*' => 55];
invokeMethod (iterable $objects, string $method, …$args): array
Ruft auf jedem Objekt in einer iterierbaren Struktur eine Methode auf und gibt ein Array der Ergebnisse zurück.
$objects = ['a' => $obj1, 'b' => $obj2];
$array = Arrays::invokeMethod($objects, 'foo', 1, 2);
// $array = ['a' => $obj1->foo(1, 2), 'b' => $obj2->foo(1, 2)];
isList (mixed $value): bool
Prüft, ob das Array von null an aufsteigend mit numerischen Schlüsseln indiziert ist, also eine Liste ist.
Arrays::isList(['a', 'b', 'c']); // true
Arrays::isList([4 => 1, 2, 3]); // false
Arrays::isList(['a' => 1, 'b' => 2]); // false
last (array $array, ?callable $predicate=null, ?callable $else=null): mixed
Gibt das letzte Element zurück (das dem angegebenen Prädikat entspricht, sofern eines angegeben ist). Gibt es kein solches
Element, wird das Ergebnis des Aufrufs von $else oder null zurückgegeben. Das $predicate hat die
Signatur function ($value, int|string $key, array $array): bool.
Anders als end() verändert die Methode den internen Zeiger nicht. Die Parameter $predicate und
$else gibt es seit Version 4.0.4.
Arrays::last([1, 2, 3]); // 3
Arrays::last([1, 2, 3], fn($v) => $v < 3); // 2
Arrays::last([]); // null
Arrays::last([], else: fn() => false); // false
Siehe first().
lastKey (array $array, ?callable $predicate=null): int|string|null
Gibt den Schlüssel des letzten Elements zurück (das dem angegebenen Prädikat entspricht, sofern eines angegeben ist), oder
null, wenn es kein solches Element gibt. Das $predicate hat die Signatur
function ($value, int|string $key, array $array): bool.
Arrays::lastKey([1, 2, 3]); // 2
Arrays::lastKey([1, 2, 3], fn($v) => $v < 3); // 1
Arrays::lastKey(['a' => 1, 'b' => 2]); // 'b'
Arrays::lastKey([]); // null
Siehe firstKey().
map (array $array, callable $transformer): array
Ruft $transformer für alle Elemente des Arrays auf und gibt ein Array der Rückgabewerte zurück. Der Callback
hat die Signatur function ($value, $key, array $array): mixed.
$array = ['foo', 'bar', 'baz'];
$res = Arrays::map($array, fn($value) => $value . $value);
// $res = ['foofoo', 'barbar', 'bazbaz']
mapWithKeys (array $array, callable $transformer): array
Erzeugt ein neues Array, indem es die Werte und Schlüssel des ursprünglichen Arrays transformiert. Die Funktion
$transformer hat die Signatur function ($value, $key, array $array): ?array{$newKey, $newValue}. Gibt
$transformer den Wert null zurück, wird das Element übersprungen. Bei den behaltenen Elementen dient
das erste Element des zurückgegebenen Arrays als neuer Schlüssel und das zweite als neuer Wert.
$array = ['a' => 1, 'b' => 2];
$result = Arrays::mapWithKeys($array, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
Diese Methode ist in Situationen nützlich, in denen Sie die Struktur eines Arrays ändern müssen (Schlüssel und Werte zugleich) oder Elemente während der Transformation herausfiltern wollen (indem Sie für unerwünschte Elemente null zurückgeben).
mergeTree (array $array1, array $array2): array
Führt zwei Arrays rekursiv zusammen. Das ist zum Beispiel zum Zusammenführen von Baumstrukturen nützlich. Es gelten
dieselben Regeln wie beim Operator + für Arrays: Die Schlüssel-Wert-Paare des zweiten Arrays werden dem ersten
hinzugefügt, und bei einer Kollision der Schlüssel bleibt der Wert aus dem ersten Array erhalten.
$array1 = ['color' => ['favorite' => 'red'], 5];
$array2 = [10, 'color' => ['favorite' => 'green', 'blue']];
$array = Arrays::mergeTree($array1, $array2);
// $array = ['color' => ['favorite' => 'red', 'blue'], 5];
Die Werte aus dem zweiten Array werden immer ans Ende des ersten angehängt. Dass der Wert 10 aus dem zweiten
Array verschwindet, mag etwas verwirrend wirken. Man muss sich klarmachen, dass diesem Wert ebenso wie dem Wert 5 im
ersten Array derselbe numerische Schlüssel 0 zugewiesen ist. Deshalb enthält das resultierende Array für diesen
Schlüssel nur das Element aus dem ersten Array.
normalize (array $array, ?string $filling=null): array
Normalisiert ein Array in ein assoziatives Array. Numerische Schlüssel werden durch ihre Werte ersetzt, und der neue Wert ist
$filling.
$array = Arrays::normalize([1 => 'first', 'a' => 'second']);
// $array = ['first' => null, 'a' => 'second'];
$array = Arrays::normalize([1 => 'first', 'a' => 'second'], 'foobar');
// $array = ['first' => 'foobar', 'a' => 'second'];
pick (array &$array, string|int $key, mixed $default=null): mixed
Gibt den Wert des Elements mit dem Schlüssel $key zurück und entfernt es aus dem Array. Existiert das Element
nicht, wirft die Methode eine Exception oder gibt $default zurück, sofern angegeben.
$array = [1 => 'foo', 'x' => 'bar'];
$a = Arrays::pick($array, 'x');
// $a = 'bar'
$b = Arrays::pick($array, 'not-exists', 'foobar');
// $b = 'foobar'
$c = Arrays::pick($array, 'not-exists');
// wirft Nette\InvalidArgumentException
renameKey (array &$array, string|int $oldKey, string|int $newKey): bool
Benennt einen Schlüssel im Array um. Gibt true zurück, wenn der Schlüssel im Array gefunden wurde.
$array = ['first' => 10, 'second' => 20];
Arrays::renameKey($array, 'first', 'renamed');
// $array = ['renamed' => 10, 'second' => 20];
getKeyOffset (array $array, string|int $key): ?int
Gibt die von null an gezählte Position des angegebenen Array-Schlüssels zurück. Gibt null zurück, wenn der
Schlüssel nicht gefunden wird.
$array = ['first' => 10, 'second' => 20];
$position = Arrays::getKeyOffset($array, 'first'); // gibt 0 zurück
$position = Arrays::getKeyOffset($array, 'second'); // gibt 1 zurück
$position = Arrays::getKeyOffset($array, 'not-exists'); // gibt null zurück
some (array $array, callable $predicate): bool
Prüft, ob mindestens ein Element des Arrays den Test besteht, den der übergebene Callback $predicate mit der
Signatur function ($value, $key, array $array): bool umsetzt.
$array = [1, 2, 3, 4];
$isEven = fn($value) => $value % 2 === 0;
$res = Arrays::some($array, $isEven); // true
Siehe every().
toKey (mixed $value): string|int
Wandelt einen Wert in einen Array-Schlüssel um, also in eine ganze Zahl oder einen String. Fließkommazahlen werden
abgeschnitten, boolesche Werte in 0 oder 1 umgewandelt, null wird zum leeren String, und Objekte werfen
eine Exception.
Arrays::toKey('1'); // 1
Arrays::toKey('01'); // '01'
toObject (iterable $array, object $object): object
Kopiert die Elemente der iterierbaren Struktur $array in das Objekt $object und gibt dieses Objekt
anschließend zurück.
$obj = new stdClass;
$array = ['foo' => 1, 'bar' => 2];
Arrays::toObject($array, $obj); // es setzt $obj->foo = 1; $obj->bar = 2;
wrap (array $array, string
$prefix='', string $suffix=''): array
Wandelt jedes Element des Arrays in einen String um und umschließt es mit $prefix und $suffix.
$array = Arrays::wrap(['a' => 'red', 'b' => 'green'], '<<', '>>');
// $array = ['a' => '<<red>>', 'b' => '<<green>>'];
ArrayHash
Das Objekt Nette\Utils\ArrayHash ist ein Nachfahre
der generischen Klasse stdClass und erweitert sie um die Fähigkeit, sich wie ein Array behandeln zu lassen, also
etwa auf die Mitglieder über eckige Klammern zuzugreifen:
$hash = new Nette\Utils\ArrayHash;
$hash['foo'] = 123;
$hash->bar = 456; // die Objektschreibweise funktioniert ebenfalls
$hash->foo; // 123
Die Anzahl der Elemente liefert Ihnen die Funktion count($hash).
Über das Objekt lässt sich genauso iterieren wie über ein Array, auch mit Referenz:
foreach ($hash as $key => $value) {
// ...
}
foreach ($hash as $key => &$value) {
$value = 'new value';
}
Ein bestehendes Array lässt sich mit der statischen Methode from() in ein ArrayHash verwandeln:
$array = ['foo' => 123, 'bar' => 456];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->foo; // 123
$hash->bar; // 456
Die Umwandlung ist rekursiv: Auch alle Unter-Arrays werden in ArrayHash-Objekte umgewandelt.
$array = ['foo' => 123, 'inner' => ['a' => 'b']];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->inner; // Objekt ArrayHash
$hash->inner->a; // 'b'
$hash['inner']['a']; // 'b'
Dieses rekursive Verhalten lässt sich über den zweiten Parameter abschalten:
$hash = Nette\Utils\ArrayHash::from($array, false);
$hash->inner; // array
Die Rückumwandlung in ein Array erledigt der Cast (array):
$array = (array) $hash;
ArrayList
Nette\Utils\ArrayList stellt ein lineares Array dar, dessen Indexe nur von 0 an aufsteigende ganze Zahlen sind.
$list = new Nette\Utils\ArrayList;
$list[] = 'a';
$list[] = 'b';
$list[] = 'c';
// ArrayList(0 => 'a', 1 => 'b', 2 => 'c')
count($list); // 3
Ein bestehendes Array lässt sich mit der statischen Methode from() in eine ArrayList verwandeln:
$array = ['foo', 'bar'];
$list = Nette\Utils\ArrayList::from($array);
Die Anzahl der Elemente liefert Ihnen die Funktion count($list).
Über das Objekt lässt sich genauso iterieren wie über ein Array, auch mit Referenz:
foreach ($list as $key => $value) {
// ...
}
foreach ($list as $key => &$value) {
$value = 'new value';
}
Der Zugriff auf Schlüssel außerhalb des erlaubten Bereichs (0 bis count-1) oder der Versuch, nicht ganzzahlige Schlüssel zu
setzen, wirft eine Nette\OutOfRangeException:
echo $list[-1]; // wirft Nette\OutOfRangeException
unset($list[30]); // wirft Nette\OutOfRangeException
Das Entfernen eines Schlüssels führt dazu, dass die Elemente neu nummeriert werden:
unset($list[1]);
// ArrayList(0 => 'a', 1 => 'c')
Ein neues Element lässt sich mit der Methode prepend() am Anfang hinzufügen:
$list->prepend('d');
// ArrayList(0 => 'd', 1 => 'a', 2 => 'c')