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')
Version: 4.x