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')
Version: 4.0