Delo s polji
Ta stran je posvečena razredom Nette\Utils\Arrays, ArrayHash in ArrayList, ki se nanašajo na polja.
Namestitev:
composer require nette/utils
Arrays
Nette\Utils\Arrays je statični razred, ki vsebuje uporabne funkcije za delo s polji. Njegov ekvivalent za iteratorje je Nette\Utils\Iterables.
Naslednji primeri predpostavljajo ustvarjen alias:
use Nette\Utils\Arrays;
associate (array $array, mixed $path): array|\stdClass
Funkcija fleksibilno pretvori polje $array
v asociativno polje ali objekte glede na podano pot
$path
. Pot je lahko niz ali polje. Sestavljajo jo imena ključev vhodnega polja in operatorji, kot so ‘[]’,
‘->’, ‘=’, in ‘|’. V primeru neveljavne poti sproži Nette\InvalidArgumentException
.
// pretvorba v asociativno polje po enostavnem ključu
$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]]
// dodelitev vrednosti iz enega ključa drugemu z uporabo operatorja =
$result = Arrays::associate($arr, 'name=age'); // ali ['name', '=', 'age']
// $result = ['John' => 11, 'Mary' => null, ...]
// ustvarjanje objekta z uporabo operatorja ->
$result = Arrays::associate($arr, '->name'); // ali ['->', 'name']
// $result = (object) ['John' => ['name' => 'John', 'age' => 11], 'Mary' => ['name' => 'Mary', 'age' => null]]
// kombinacija ključev z uporabo operatorja |
$result = Arrays::associate($arr, 'name|age'); // ali ['name', '|', 'age']
// $result: ['John' => ['name' => 'John', 'age' => 11], 'Paul' => ['name' => 'Paul', 'age' => 44]]
// dodajanje v polje z uporabo []
$result = Arrays::associate($arr, 'name[]'); // ali ['name', '[]']
// $result: ['John' => [['name' => 'John', 'age' => 22], ['name' => 'John', 'age' => 11]]]
contains (array $array, $value): bool
Preveri polje za prisotnost vrednosti. Uporablja strogo primerjavo (===
).
Arrays::contains([1, 2, 3], 1); // true
Arrays::contains(['1', false], 1); // false
every (array $array, callable $predicate): bool
Preveri, ali vsi elementi v polju prestanejo test, implementiran v $predicate
s signaturo
function ($value, $key, array $array): bool
.
$array = [1, 30, 39, 29, 10, 13];
$isBelowThreshold = fn($value) => $value < 40;
$res = Arrays::every($array, $isBelowThreshold); // true
Glejte some().
filter (array $array, callable $predicate): array
Vrne novo polje, ki vsebuje vse pare ključ-vrednost, ki ustrezajo podanemu predikatu. Povratni klic ima signaturo
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
Vrne prvi element (ki ustreza predikatu, če je podan). Če tak element ne obstaja, vrne rezultat klica $else
ali
null. Parameter $predicate
ima signaturo function ($value, int|string $key, array $array): bool
.
Ne spremeni notranjega kazalca za razliko od reset()
. Parametra $predicate
in $else
obstajata od različice 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
Glejte last().
firstKey (array $array, ?callable $predicate=null): int|string|null
Vrne ključ prvega elementa (ki ustreza predikatu, če je podan) ali null, če tak element ne obstaja. Predikat
$predicate
ima signaturo 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
Glejte lastKey().
flatten (array $array, bool $preserveKeys=false): array
Združi večnivojsko polje v ravno.
$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
Vrne element $array[$key]
. Če ne obstaja, sproži bodisi izjemo Nette\InvalidArgumentException
ali,
če je podan tretji parameter $default
, vrne tega.
// če $array['foo'] ne obstaja, sproži izjemo
$value = Arrays::get($array, 'foo');
// če $array['foo'] ne obstaja, vrne 'bar'
$value = Arrays::get($array, 'foo', 'bar');
Ključ $key
je lahko tudi polje.
$array = ['color' => ['favorite' => 'red'], 5];
$value = Arrays::get($array, ['color', 'favorite']);
// vrne 'red'
getRef (array &$array, string|int|array $key): mixed
Pridobi referenco na določen element polja. Če element ne obstaja, bo ustvarjen z vrednostjo null.
$valueRef = & Arrays::getRef($array, 'foo');
// vrne referenco na $array['foo']
Tako kot funkcija get() zna delati z večdimenzionalnimi polji.
$value = & Arrays::getRef($array, ['color', 'favorite']);
// vrne referenco na $array['color']['favorite']
grep (array $array, string $pattern, bool $invert=false): array
Vrne samo tiste elemente polja, katerih vrednost ustreza regularnemu izrazu $pattern
. Če je $invert
true
, vrne nasprotno elemente, ki ne ustrezajo. Napaka pri prevajanju ali obdelavi izraza sproži izjemo
Nette\RegexpException
.
$filteredArray = Arrays::grep($array, '~^\d+$~');
// vrne samo elemente polja, sestavljene iz števk
insertAfter (array &$array, string|int|null $key, array $inserted): void
Vstavi vsebino polja $inserted
v polje $array
takoj za element s ključem $key
. Če je
$key
null
(ali ga v polju ni), se vstavi na konec.
$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
Vstavi vsebino polja $inserted
v polje $array
pred element s ključem $key
. Če je
$key
null
(ali ga v polju ni), se vstavi na začetek.
$array = ['first' => 10, 'second' => 20];
Arrays::insertBefore($array, 'first', ['hello' => 'world']);
// $array = ['hello' => 'world', 'first' => 10, 'second' => 20];
invoke (iterable $callbacks, …$args): array
Kliče vse povratne klice in vrne polje rezultatov.
$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
Kliče metodo na vsakem objektu v polju in vrne polje rezultatov.
$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
Preveri, ali je polje indeksirano po naraščajočem zaporedju numeričnih ključev od nič, t.i. seznam (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
Vrne zadnji element (ki ustreza predikatu, če je podan). Če tak element ne obstaja, vrne rezultat klica $else
ali null. Parameter $predicate
ima signatururo
function ($value, int|string $key, array $array): bool
.
Ne spremeni notranjega kazalca za razliko od end()
. Parametra $predicate
in $else
obstajata od različice 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
Glejte first().
lastKey (array $array, ?callable $predicate=null): int|string|null
Vrne ključ zadnjega elementa (ki ustreza predikatu, če je podan) ali null, če tak element ne obstaja. Predikat
$predicate
ima signaturo 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
Glejte firstKey().
map (array $array, callable $transformer): array
Kliče $transformer
na vse elemente v polju in vrne polje vrnjenih vrednosti. Povratni klic ima signaturo
function ($value, $key, array $array): bool
.
$array = ['foo', 'bar', 'baz'];
$res = Arrays::map($array, fn($value) => $value . $value);
// $res = ['foofoo', 'barbar', 'bazbaz']
mapWithKeys (array $array, callable $transformer): array
Ustvari novo polje s transformacijo vrednosti in ključev prvotnega polja. Funkcija $transformer
ima signaturo
function ($value, $key, array $array): ?array{$newKey, $newValue}
. Če $transformer
vrne
null
, je element preskočen. Za ohranjene elemente se prvi element vrnjenega polja uporabi kot nov ključ, drugi
element pa kot nova vrednost.
$array = ['a' => 1, 'b' => 2, 'c' => 3];
$result = Arrays::mapWithKeys($array, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
Ta metoda je uporabna v situacijah, ko morate spremeniti strukturo polja (ključe in vrednosti hkrati) ali filtrirati elemente med transformacijo (z vračanjem null za neželene elemente).
mergeTree (array $array1, array $array2): array
Rekurzivno združi dve polji. Uporabno je na primer za združevanje drevesnih struktur. Pri združevanju sledi istim pravilom
kot operator +
, uporabljen na poljih, tj. prvemu polju dodaja pare ključ/vrednost iz drugega polja in v primeru
kolizije ključev ohrani vrednost iz prvega polja.
$array1 = ['color' => ['favorite' => 'red'], 5];
$array2 = [10, 'color' => ['favorite' => 'green', 'blue']];
$array = Arrays::mergeTree($array1, $array2);
// $array = ['color' => ['favorite' => 'red', 'blue'], 5];
Vrednosti iz drugega polja so vedno dodane na konec prvega. Malo zmedeno se lahko zdi izginotje vrednosti 10
iz
drugega polja. Treba se je zavedati, da imata ta vrednost in prav tako vrednost 5
v prvem polju dodeljen isti
numerični ključ 0
, zato je v končnem polju samo element iz prvega polja.
normalize (array $array, ?string $filling=null): array
Normalizira polje v asociativno polje. Numerične ključe nadomesti z njihovimi vrednostmi, nova vrednost bo
$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
Vrne in odstrani vrednost elementa iz polja. Če ne obstaja, sproži izjemo ali vrne vrednost $default
, če je
podana.
$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');
// sproži Nette\InvalidArgumentException
renameKey (array &$array, string|int $oldKey, string|int $newKey): bool
Preimenuje ključ v polju. Vrne true
, če je bil ključ najden v polju.
$array = ['first' => 10, 'second' => 20];
Arrays::renameKey($array, 'first', 'renamed');
// $array = ['renamed' => 10, 'second' => 20];
getKeyOffset (array $array, string|int $key): ?int
Vrne položaj danega ključa v polju. Položaj je oštevilčen od 0. V primeru, da ključ ni najden, funkcija vrne
null
.
$array = ['first' => 10, 'second' => 20];
$position = Arrays::getKeyOffset($array, 'first'); // vrne 0
$position = Arrays::getKeyOffset($array, 'second'); // vrne 1
$position = Arrays::getKeyOffset($array, 'not-exists'); // vrne null
some (array $array, callable $predicate): bool
Preveri, ali vsaj en element v polju prestane test, implementiran v $predicate
s signaturo
function ($value, $key, array $array): bool
.
$array = [1, 2, 3, 4];
$isEven = fn($value) => $value % 2 === 0;
$res = Arrays::some($array, $isEven); // true
Glejte every().
toKey (mixed $key): string|int
Pretvori vrednost v ključ polja, ki je bodisi celo število (integer) ali niz.
Arrays::toKey('1'); // 1
Arrays::toKey('01'); // '01'
toObject (iterable $array, object $object): object
Kopira elemente polja $array
v objekt $object
, ki ga nato vrne.
$obj = new stdClass;
$array = ['foo' => 1, 'bar' => 2];
Arrays::toObject($array, $obj); // nastavi $obj->foo = 1; $obj->bar = 2;
wrap (array $array, string
$prefix=''
, string $suffix=''
): array
Vsak element v polju pretvori v niz in ga ovije s predpono $prefix
in pripono $suffix
.
$array = Arrays::wrap(['a' => 'red', 'b' => 'green'], '<<', '>>');
// $array = ['a' => '<<red>>', 'b' => '<<green>>'];
ArrayHash
Objekt Nette\Utils\ArrayHash je potomec generičnega razreda stdClass in ga razširja z zmožnostjo obravnavanja kot polja, torej na primer dostopanja do članov prek oglatih oklepajev:
$hash = new Nette\Utils\ArrayHash;
$hash['foo'] = 123;
$hash->bar = 456; // hkrati deluje tudi objektni zapis
$hash->foo; // 123
Lahko uporabljate funkcijo count($hash)
za ugotavljanje števila elementov.
Nad objektom je mogoče iterirati enako kot v primeru polja, tudi z referenco:
foreach ($hash as $key => $value) {
// ...
}
foreach ($hash as $key => &$value) {
$value = 'new value';
}
Obstoječe polje lahko pretvorimo v ArrayHash
z metodo from()
:
$array = ['foo' => 123, 'bar' => 456];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->foo; // 123
$hash->bar; // 456
Pretvorba je rekurzivna:
$array = ['foo' => 123, 'inner' => ['a' => 'b']];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->inner; // objekt ArrayHash
$hash->inner->a; // 'b'
$hash['inner']['a']; // 'b'
To lahko preprečite z drugim parametrom:
$hash = Nette\Utils\ArrayHash::from($array, false);
$hash->inner; // polje
Transformacija nazaj v polje:
$array = (array) $hash;
ArrayList
Nette\Utils\ArrayList predstavlja linearno polje, kjer so indeksi samo cela števila naraščajoče od 0.
$list = new Nette\Utils\ArrayList;
$list[] = 'a';
$list[] = 'b';
$list[] = 'c';
// ArrayList(0 => 'a', 1 => 'b', 2 => 'c')
count($list); // 3
Obstoječe polje lahko pretvorimo v ArrayList
z metodo from()
:
$array = ['foo', 'bar'];
$list = Nette\Utils\ArrayList::from($array);
Lahko uporabljate funkcijo count($list)
za ugotavljanje števila elementov.
Nad objektom je mogoče iterirati enako kot v primeru polja, tudi z referenco:
foreach ($list as $key => $value) {
// ...
}
foreach ($list as $key => &$value) {
$value = 'new value';
}
Dostop do ključev izven dovoljenih vrednosti sproži izjemo Nette\OutOfRangeException
:
echo $list[-1]; // sproži Nette\OutOfRangeException
unset($list[30]); // sproži Nette\OutOfRangeException
Odstranitev ključa povzroči preštevilčenje elementov:
unset($list[1]);
// ArrayList(0 => 'a', 1 => 'c')
Nov element lahko dodate na začetek z metodo prepend()
:
$list->prepend('d');
// ArrayList(0 => 'd', 1 => 'a', 2 => 'c')