Arbeiten mit Arrays
Diese Seite widmet sich den Klassen Nette\Utils\Arrays, ArrayHash und ArrayList, die sich auf Arrays beziehen.
Installation:
composer require nette/utils
Arrays
Nette\Utils\Arrays ist eine statische Klasse, die nützliche Funktionen für die Arbeit mit Arrays enthält. Ihr Analogon für Iteratoren ist Nette\Utils\Iterables.
Die folgenden Beispiele setzen voraus, dass ein Alias erstellt wurde:
use Nette\Utils\Arrays;
associate (array $array, mixed $path): array|\stdClass
Die Funktion transformiert das Array $array
flexibel in ein assoziatives Array oder Objekte gemäß dem
angegebenen Pfad $path
. Der Pfad kann ein String oder ein Array sein. Er besteht aus den Schlüsselnamen des
Eingabearrays und Operatoren wie ‘[]’, ‘->’, ‘=’, und ‘|’. Wirft Nette\InvalidArgumentException
,
wenn der Pfad ungültig ist.
// Umwandlung in ein assoziatives Array nach einem einfachen Schlüssel
$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 von Werten von einem Schlüssel zu einem anderen unter Verwendung des Operators =
$result = Arrays::associate($arr, 'name=age'); // oder ['name', '=', 'age']
// $result = ['John' => 11, 'Mary' => null, ...]
// Erstellung eines Objekts unter Verwendung des Operators ->
$result = Arrays::associate($arr, '->name'); // oder ['->', 'name']
// $result = (object) ['John' => ['name' => 'John', 'age' => 11], 'Mary' => ['name' => 'Mary', 'age' => null]]
// Kombination von Schlüsseln unter Verwendung des Operators |
$result = Arrays::associate($arr, 'name|age'); // oder ['name', '|', 'age']
// $result: ['John' => ['name' => 'John', 'age' => 11], 'Paul' => ['name' => 'Paul', 'age' => 44]]
// Hinzufügen zum Array unter Verwendung von []
$result = Arrays::associate($arr, 'name[]'); // oder ['name', '[]']
// $result: ['John' => [['name' => 'John', 'age' => 22], ['name' => 'John', 'age' => 11]]]
contains (array $array, $value): bool
Testet ein Array auf die Anwesenheit eines Wertes. Verwendet einen strikten Vergleich (===
).
Arrays::contains([1, 2, 3], 1); // true
Arrays::contains(['1', false], 1); // false
every (array $array, callable $predicate): bool
Testet, ob alle Elemente im Array den Test bestehen, der in $predicate
mit der Signatur
function ($value, $key, array $array): bool
implementiert ist.
$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 zurück, das alle Schlüssel-Wert-Paare enthält, die dem angegebenen Prädikat 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,
);
// ['a' => 1, 'b' => 2]
first (array $array, ?callable $predicate=null, ?callable $else=null): mixed
Gibt das erste Element zurück (das dem Prädikat entspricht, falls angegeben). Wenn kein solches Element existiert, gibt es
das Ergebnis des Aufrufs von $else
oder null zurück. Der Parameter $predicate
hat die Signatur
function ($value, int|string $key, array $array): bool
.
Ändert den internen Zeiger im Gegensatz zu reset()
nicht. Die Parameter $predicate
und
$else
existieren 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 Prädikat entspricht, falls angegeben) oder null, wenn kein solches
Element existiert. Das Prädikat $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
Vereinigt ein mehrdimensionales Array zu einem flachen Array.
$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. Wenn es nicht existiert, wird entweder eine Ausnahme
Nette\InvalidArgumentException
geworfen oder, wenn der dritte Parameter $default
angegeben ist, dieser
zurückgegeben.
// wenn $array['foo'] nicht existiert, wird eine Ausnahme geworfen
$value = Arrays::get($array, 'foo');
// wenn $array['foo'] nicht existiert, wird 'bar' zurückgegeben
$value = Arrays::get($array, 'foo', 'bar');
Der Schlüssel $key
kann auch ein Array sein.
$array = ['color' => ['favorite' => 'red'], 5];
$value = Arrays::get($array, ['color', 'favorite']);
// gibt 'red' zurück
getRef (array &$array, string|int|array $key): mixed
Gibt eine Referenz auf das angegebene Array-Element zurück. Wenn das Element nicht existiert, wird es mit dem Wert null erstellt.
$valueRef = & Arrays::getRef($array, 'foo');
// gibt eine Referenz auf $array['foo'] zurück
Wie die Funktion get() kann sie auch mit mehrdimensionalen Arrays arbeiten.
$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 Array-Elemente zurück, deren Wert dem regulären Ausdruck $pattern
entspricht. Wenn
$invert
true
ist, werden umgekehrt die Elemente zurückgegeben, die nicht entsprechen. Ein Fehler bei
der Kompilierung oder Verarbeitung des Ausdrucks wirft eine Ausnahme Nette\RegexpException
.
$filteredArray = Arrays::grep($array, '~^\d+$~');
// gibt nur 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
in das Array $array
direkt nach dem Element mit dem Schlüssel
$key
ein. Wenn $key
null
ist (oder nicht im Array vorhanden ist), wird es 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
in das Array $array
vor dem Element mit dem Schlüssel
$key
ein. Wenn $key
null
ist (oder nicht im Array vorhanden ist), wird es 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 auf und gibt ein Array von Ergebnissen 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 eine Methode auf jedem Objekt im Array auf und gibt ein Array von Ergebnissen 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 (array $array): bool
Überprüft, ob das Array nach einer aufsteigenden Reihe numerischer Schlüssel von Null an indiziert ist, a.k.a. eine Liste.
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 Prädikat entspricht, falls angegeben). Wenn kein solches Element existiert, gibt es
das Ergebnis des Aufrufs von $else
oder null zurück. Der Parameter $predicate
hat die Signatur
function ($value, int|string $key, array $array): bool
.
Ändert den internen Zeiger im Gegensatz zu end()
nicht. Die Parameter $predicate
und
$else
existieren 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 Prädikat entspricht, falls angegeben) oder null, wenn kein solches
Element existiert. Das Prädikat $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
auf alle Elemente im Array auf und gibt ein Array der zurückgegebenen Werte 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 durch Transformation der Werte und Schlüssel des ursprünglichen Arrays. Die Funktion
$transformer
hat die Signatur function ($value, $key, array $array): ?array{$newKey, $newValue}
. Wenn
$transformer
null
zurückgibt, wird das Element übersprungen. Für beibehaltene Elemente wird das erste
Element des zurückgegebenen Arrays als neuer Schlüssel und das zweite Element als neuer Wert verwendet.
$array = ['a' => 1, 'b' => 2];
$result = Arrays::mapWithKeys($array, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
Diese Methode ist nützlich in Situationen, in denen Sie die Struktur eines Arrays ändern müssen (Schlüssel und Werte gleichzeitig) oder Elemente während der Transformation filtern müssen (indem Sie null für unerwünschte Elemente zurückgeben).
mergeTree (array $array1, array $array2): array
Führt zwei Arrays rekursiv zusammen. Dies ist beispielsweise nützlich zum Zusammenführen von Baumstrukturen. Beim
Zusammenführen gelten die gleichen Regeln wie für den Operator +
, der auf Arrays angewendet wird, d.h. dem ersten
Array werden Schlüssel/Wert-Paare aus dem zweiten Array hinzugefügt, und im Falle von Schlüsselkollisionen wird der Wert aus
dem ersten Array beibehalten.
$array1 = ['color' => ['favorite' => 'red'], 5];
$array2 = [10, 'color' => ['favorite' => 'green', 'blue']];
$array = Arrays::mergeTree($array1, $array2);
// $array = ['color' => ['favorite' => 'red', 'blue'], 5];
Werte aus dem zweiten Array werden immer am Ende des ersten hinzugefügt. Etwas verwirrend mag das Verschwinden des Wertes
10
aus dem zweiten Array erscheinen. Es ist zu beachten, dass dieser Wert, ebenso wie der Wert 5
im
ersten Array, denselben numerischen Schlüssel 0
zugewiesen bekommen hat, weshalb im resultierenden Array nur das
Element aus dem ersten Array vorhanden ist.
normalize (array $array, ?string $filling=null): array
Normalisiert ein Array zu einem assoziativen Array. Numerische Schlüssel werden durch ihre Werte ersetzt, der neue Wert wird
$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 eines Elements aus dem Array zurück und entfernt ihn. Wenn er nicht existiert, wird eine Ausnahme geworfen, oder
der Wert $default
zurückgegeben, falls angegeben.
$array = [1 => 'foo', null => 'bar'];
$a = Arrays::pick($array, null);
// $a = 'bar'
$b = Arrays::pick($array, 'not-exists', 'foobar');
// $b = 'foobar'
$c = Arrays::pick($array, 'not-exists');
// throws 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 Position des angegebenen Schlüssels im Array zurück. Die Position ist ab 0 nummeriert. Falls der Schlüssel nicht
gefunden wird, gibt die Funktion null
zurück.
$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
Testet, ob mindestens ein Element im Array den Test besteht, der in $predicate
mit der Signatur
function ($value, $key, array $array): bool
implementiert ist.
$array = [1, 2, 3, 4];
$isEven = fn($value) => $value % 2 === 0;
$res = Arrays::some($array, $isEven); // true
Siehe every().
toKey (mixed $key): string|int
Konvertiert einen Wert in einen Array-Schlüssel, der entweder ein Integer oder ein String ist.
Arrays::toKey('1'); // 1
Arrays::toKey('01'); // '01'
toObject (iterable $array, object $object): object
Kopiert die Elemente des Arrays $array
in das Objekt $object
, das dann zurückgegeben wird.
$obj = new stdClass;
$array = ['foo' => 1, 'bar' => 2];
Arrays::toObject($array, $obj); // setzt $obj->foo = 1; $obj->bar = 2;
wrap (array $array, string
$prefix=''
, string $suffix=''
): array
Konvertiert jedes Element im Array in einen String und umgibt es mit dem Präfix $prefix
und dem Suffix
$suffix
.
$array = Arrays::wrap(['a' => 'red', 'b' => 'green'], '<<', '>>');
// $array = ['a' => '<<red>>', 'b' => '<<green>>'];
ArrayHash
Das Objekt Nette\Utils\ArrayHash ist ein Nachkomme der generischen Klasse stdClass und erweitert diese um die Fähigkeit, sie wie ein Array zu behandeln, d.h. zum Beispiel auf Mitglieder über eckige Klammern zuzugreifen:
$hash = new Nette\Utils\ArrayHash;
$hash['foo'] = 123;
$hash->bar = 456; // gleichzeitig funktioniert auch die Objektnotation
$hash->foo; // 123
Die Funktion count($hash)
kann verwendet werden, um die Anzahl der Elemente zu ermitteln.
Über das Objekt kann wie über ein Array iteriert werden, auch mit Referenz:
foreach ($hash as $key => $value) {
// ...
}
foreach ($hash as $key => &$value) {
$value = 'new value';
}
Ein vorhandenes Array kann mit der Methode from()
in einen ArrayHash
transformiert werden:
$array = ['foo' => 123, 'bar' => 456];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->foo; // 123
$hash->bar; // 456
Die Konvertierung ist rekursiv:
$array = ['foo' => 123, 'inner' => ['a' => 'b']];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->inner; // Objekt ArrayHash
$hash->inner->a; // 'b'
$hash['inner']['a']; // 'b'
Dies kann durch den zweiten Parameter verhindert werden:
$hash = Nette\Utils\ArrayHash::from($array, false);
$hash->inner; // Array
Transformation zurück in ein Array:
$array = (array) $hash;
ArrayList
Nette\Utils\ArrayList stellt ein lineares Array dar, bei dem die Indizes nur ganze Zahlen aufsteigend ab 0 sind.
$list = new Nette\Utils\ArrayList;
$list[] = 'a';
$list[] = 'b';
$list[] = 'c';
// ArrayList(0 => 'a', 1 => 'b', 2 => 'c')
count($list); // 3
Ein vorhandenes Array kann mit der Methode from()
in einen ArrayList
transformiert werden:
$array = ['foo', 'bar'];
$list = Nette\Utils\ArrayList::from($array);
Die Funktion count($list)
kann verwendet werden, um die Anzahl der Elemente zu ermitteln.
Über das Objekt kann wie über ein Array iteriert werden, auch mit Referenz:
foreach ($list as $key => $value) {
// ...
}
foreach ($list as $key => &$value) {
$value = 'new value';
}
Der Zugriff auf Schlüssel außerhalb der erlaubten Werte wirft eine Ausnahme Nette\OutOfRangeException
:
echo $list[-1]; // wirft Nette\OutOfRangeException
unset($list[30]); // wirft Nette\OutOfRangeException
Das Entfernen eines Schlüssels führt zur Neuindizierung der Elemente:
unset($list[1]);
// ArrayList(0 => 'a', 1 => 'c')
Ein neues Element kann mit der Methode prepend()
am Anfang hinzugefügt werden:
$list->prepend('d');
// ArrayList(0 => 'd', 1 => 'a', 2 => 'c')