Lucrul cu array-uri
Această pagină este dedicată claselor Nette\Utils\Arrays, ArrayHash și ArrayList, care se referă la array-uri.
Instalare:
composer require nette/utils
Arrays
Nette\Utils\Arrays este o clasă statică ce conține funcții utile pentru lucrul cu array-uri. Echivalentul său pentru iteratori este Nette\Utils\Iterables.
Următoarele exemple presupun crearea unui alias:
use Nette\Utils\Arrays;
associate (array $array, mixed $path): array|\stdClass
Funcția transformă flexibil array-ul $array
într-un array asociativ sau obiecte conform căii specificate
$path
. Calea poate fi un șir sau un array. Este formată din numele cheilor array-ului de intrare și operatori
precum ‘[]’, ‘->’, ‘=’, și ‘|’. Aruncă Nette\InvalidArgumentException
în cazul în care calea
este invalidă.
// conversie la array asociativ după o cheie simplă
$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]]
// atribuirea valorilor de la o cheie la alta folosind operatorul =
$result = Arrays::associate($arr, 'name=age'); // sau ['name', '=', 'age']
// $result = ['John' => 11, 'Mary' => null, ...]
// crearea unui obiect folosind operatorul ->
$result = Arrays::associate($arr, '->name'); // sau ['->', 'name']
// $result = (object) ['John' => ['name' => 'John', 'age' => 11], 'Mary' => ['name' => 'Mary', 'age' => null]]
// combinarea cheilor folosind operatorul |
$result = Arrays::associate($arr, 'name|age'); // sau ['name', '|', 'age']
// $result: ['John' => ['name' => 'John', 'age' => 11], 'Paul' => ['name' => 'Paul', 'age' => 44]]
// adăugarea într-un array folosind []
$result = Arrays::associate($arr, 'name[]'); // sau ['name', '[]']
// $result: ['John' => [['name' => 'John', 'age' => 22], ['name' => 'John', 'age' => 11]]]
contains (array $array, $value): bool
Testează array-ul pentru prezența unei valori. Utilizează comparația strictă (===
).
Arrays::contains([1, 2, 3], 1); // true
Arrays::contains(['1', false], 1); // false
every (array $array, callable $predicate): bool
Testează dacă toate elementele din array trec testul implementat în $predicate
cu semnătura
function ($value, $key, array $array): bool
.
$array = [1, 30, 39, 29, 10, 13];
$isBelowThreshold = fn($value) => $value < 40;
$res = Arrays::every($array, $isBelowThreshold); // true
Vezi some().
filter (array $array, callable $predicate): array
Returnează un nou array conținând toate perechile cheie-valoare care corespund predicatului specificat. Callback-ul are
semnătura 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
Returnează primul element (care corespunde predicatului, dacă este specificat). Dacă un astfel de element nu există,
returnează rezultatul apelării $else
sau null. Parametrul $predicate
are semnătura
function ($value, int|string $key, array $array): bool
.
Nu modifică pointerul intern, spre deosebire de reset()
. Parametrii $predicate
și
$else
există începând cu versiunea 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
Vezi last().
firstKey (array $array, ?callable $predicate=null): int|string|null
Returnează cheia primului element (care corespunde predicatului, dacă este specificat) sau null dacă un astfel de element nu
există. Predicatul $predicate
are semnătura
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
Vezi lastKey().
flatten (array $array, bool $preserveKeys=false): array
Unifică un array multi-nivel într-unul plat.
$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
Returnează elementul $array[$key]
. Dacă nu există, aruncă fie excepția
Nette\InvalidArgumentException
, fie, dacă este specificat al treilea parametru $default
, îl
returnează pe acesta.
// dacă $array['foo'] nu există, aruncă o excepție
$value = Arrays::get($array, 'foo');
// dacă $array['foo'] nu există, returnează 'bar'
$value = Arrays::get($array, 'foo', 'bar');
Cheia $key
poate fi și un array.
$array = ['color' => ['favorite' => 'red'], 5];
$value = Arrays::get($array, ['color', 'favorite']);
// returnează 'red'
getRef (array &$array, string|int|array $key): mixed
Obține o referință la elementul specificat al array-ului. Dacă elementul nu există, va fi creat cu valoarea null.
$valueRef = & Arrays::getRef($array, 'foo');
// returnează o referință la $array['foo']
La fel ca funcția get(), poate lucra cu array-uri multidimensionale.
$value = & Arrays::getRef($array, ['color', 'favorite']);
// returnează o referință la $array['color']['favorite']
grep (array $array, string $pattern, bool $invert=false): array
Returnează doar acele elemente ale array-ului a căror valoare corespunde expresiei regulate $pattern
. Dacă
$invert
este true
, returnează invers, elementele care nu corespund. O eroare la compilarea sau
procesarea expresiei aruncă excepția Nette\RegexpException
.
$filteredArray = Arrays::grep($array, '~^\d+$~');
// returnează doar elementele array-ului formate din cifre
insertAfter (array &$array, string|int|null $key, array $inserted): void
Inserează conținutul array-ului $inserted
în array-ul $array
imediat după elementul cu cheia
$key
. Dacă $key
este null
(sau nu se află în array), se inserează la sfârșit.
$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
Inserează conținutul array-ului $inserted
în array-ul $array
înainte de elementul cu cheia
$key
. Dacă $key
este null
(sau nu se află în array), se inserează la început.
$array = ['first' => 10, 'second' => 20];
Arrays::insertBefore($array, 'first', ['hello' => 'world']);
// $array = ['hello' => 'world', 'first' => 10, 'second' => 20];
invoke (iterable $callbacks, …$args): array
Invocă toate callback-urile și returnează un array de rezultate.
$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
Apelează o metodă pe fiecare obiect din array și returnează un array de rezultate.
$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
Verifică dacă array-ul este indexat conform unei serii ascendente de chei numerice de la zero, a.k.a list.
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
Returnează ultimul element (care corespunde predicatului, dacă este specificat). Dacă un astfel de element nu există,
returnează rezultatul apelării $else
sau null. Parametrul $predicate
are semnătura
function ($value, int|string $key, array $array): bool
.
Nu modifică pointerul intern, spre deosebire de end()
. Parametrii $predicate
și $else
există începând cu versiunea 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
Vezi first().
lastKey (array $array, ?callable $predicate=null): int|string|null
Returnează cheia ultimului element (care corespunde predicatului, dacă este specificat) sau null dacă un astfel de element
nu există. Predicatul $predicate
are semnătura
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
Vezi firstKey().
map (array $array, callable $transformer): array
Apelează $transformer
pe toate elementele din array și returnează un array de valori returnate. Callback-ul are
semnătura 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
Creează un nou array prin transformarea valorilor și cheilor array-ului original. Funcția $transformer
are
semnătura function ($value, $key, array $array): ?array{$newKey, $newValue}
. Dacă $transformer
returnează null
, elementul este omis. Pentru elementele păstrate, primul element al array-ului returnat este
folosit ca nouă cheie și al doilea element ca nouă valoare.
$array = ['a' => 1, 'b' => 2];
$result = Arrays::mapWithKeys($array, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
Această metodă este utilă în situații în care trebuie să schimbați structura unui array (cheile și valorile simultan) sau să filtrați elemente în timpul transformării (returnând null pentru elementele nedorite).
mergeTree (array $array1, array $array2): array
Combină recursiv două array-uri. Este util, de exemplu, pentru combinarea structurilor arborescente. La combinare, respectă
aceleași reguli ca operatorul +
aplicat pe array-uri, adică adaugă la primul array perechile cheie/valoare din al
doilea array și, în caz de coliziune a cheilor, păstrează valoarea din primul array.
$array1 = ['color' => ['favorite' => 'red'], 5];
$array2 = [10, 'color' => ['favorite' => 'green', 'blue']];
$array = Arrays::mergeTree($array1, $array2);
// $array = ['color' => ['favorite' => 'red', 'blue'], 5];
Valorile din al doilea array sunt întotdeauna adăugate la sfârșitul primului. Dispariția valorii 10
din al
doilea array poate părea puțin derutantă. Trebuie să realizăm că această valoare, la fel ca valoarea 5
din
primul array, au atribuită aceeași cheie numerică 0
, de aceea în array-ul rezultat este doar elementul din
primul array.
normalize (array $array, ?string $filling=null): array
Normalizează array-ul la un array asociativ. Cheile numerice le înlocuiește cu valorile lor, noua valoare va fi
$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
Returnează și elimină valoarea unui element din array. Dacă nu există, aruncă o excepție sau returnează valoarea
$default
, dacă este specificată.
$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
Redenumește o cheie în array. Returnează true
dacă cheia a fost găsită în array.
$array = ['first' => 10, 'second' => 20];
Arrays::renameKey($array, 'first', 'renamed');
// $array = ['renamed' => 10, 'second' => 20];
getKeyOffset (array $array, string|int $key): ?int
Returnează poziția cheii date în array. Poziția este numerotată de la 0. În cazul în care cheia nu este găsită,
funcția returnează null
.
$array = ['first' => 10, 'second' => 20];
$position = Arrays::getKeyOffset($array, 'first'); // returnează 0
$position = Arrays::getKeyOffset($array, 'second'); // returnează 1
$position = Arrays::getKeyOffset($array, 'not-exists'); // returnează null
some (array $array, callable $predicate): bool
Testează dacă cel puțin un element din array trece testul implementat în $predicate
cu semnătura
function ($value, $key, array $array): bool
.
$array = [1, 2, 3, 4];
$isEven = fn($value) => $value % 2 === 0;
$res = Arrays::some($array, $isEven); // true
Vezi every().
toKey (mixed $key): string|int
Convertește o valoare într-o cheie de array, care este fie un integer, fie un șir.
Arrays::toKey('1'); // 1
Arrays::toKey('01'); // '01'
toObject (iterable $array, object $object): object
Copiază elementele array-ului $array
în obiectul $object
, pe care apoi îl returnează.
$obj = new stdClass;
$array = ['foo' => 1, 'bar' => 2];
Arrays::toObject($array, $obj); // setează $obj->foo = 1; $obj->bar = 2;
wrap (array $array, string
$prefix=''
, string $suffix=''
): array
Fiecare element din array este convertit la șir și înconjurat cu prefixul $prefix
și sufixul
$suffix
.
$array = Arrays::wrap(['a' => 'red', 'b' => 'green'], '<<', '>>');
// $array = ['a' => '<<red>>', 'b' => '<<green>>'];
ArrayHash
Obiectul Nette\Utils\ArrayHash este un descendent
al clasei generice stdClass
și o extinde cu capacitatea de a fi tratat ca un array, adică, de exemplu, accesarea
membrilor prin paranteze drepte:
$hash = new Nette\Utils\ArrayHash;
$hash['foo'] = 123;
$hash->bar = 456; // funcționează și scrierea obiectuală
$hash->foo; // 123
Se poate utiliza funcția count($hash)
pentru a afla numărul de elemente.
Peste obiect se poate itera la fel ca în cazul unui array, chiar și cu referință:
foreach ($hash as $key => $value) {
// ...
}
foreach ($hash as $key => &$value) {
$value = 'new value';
}
Un array existent poate fi transformat în ArrayHash
prin metoda from()
:
$array = ['foo' => 123, 'bar' => 456];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->foo; // 123
$hash->bar; // 456
Conversia este recursivă:
$array = ['foo' => 123, 'inner' => ['a' => 'b']];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->inner; // obiect ArrayHash
$hash->inner->a; // 'b'
$hash['inner']['a']; // 'b'
Acest lucru poate fi prevenit cu al doilea parametru:
$hash = Nette\Utils\ArrayHash::from($array, false);
$hash->inner; // array
Transformarea înapoi în array:
$array = (array) $hash;
ArrayList
Nette\Utils\ArrayList reprezintă un array liniar, unde indicii sunt doar numere întregi crescătoare de la 0.
$list = new Nette\Utils\ArrayList;
$list[] = 'a';
$list[] = 'b';
$list[] = 'c';
// ArrayList(0 => 'a', 1 => 'b', 2 => 'c')
count($list); // 3
Un array existent poate fi transformat în ArrayList
prin metoda from()
:
$array = ['foo', 'bar'];
$list = Nette\Utils\ArrayList::from($array);
Se poate utiliza funcția count($list)
pentru a afla numărul de elemente.
Peste obiect se poate itera la fel ca în cazul unui array, chiar și cu referință:
foreach ($list as $key => $value) {
// ...
}
foreach ($list as $key => &$value) {
$value = 'new value';
}
Accesarea cheilor în afara valorilor permise aruncă excepția Nette\OutOfRangeException
:
echo $list[-1]; // aruncă Nette\OutOfRangeException
unset($list[30]); // aruncă Nette\OutOfRangeException
Eliminarea unei chei cauzează renumerotarea elementelor:
unset($list[1]);
// ArrayList(0 => 'a', 1 => 'c')
Un element nou poate fi adăugat la început prin metoda prepend()
:
$list->prepend('d');
// ArrayList(0 => 'd', 1 => 'a', 2 => 'c')