Funciones de matriz
Esta página trata sobre las clases Nette\Utils\Arrays, ArrayHash y ArrayList, relacionadas con los arrays.
Instalación:
composer require nette/utils
Arrays
Nette\Utils\Arrays es una clase estática, que contiene un puñado de prácticas funciones de array. Su equivalente para iteradores es Nette\Utils\Iterables.
Los siguientes ejemplos asumen que el siguiente alias de clase está definido:
use Nette\Utils\Arrays;
associate (array $array, mixed $path): array|\stdClass
La función transforma de forma flexible la $array
en una matriz asociativa u objetos según la ruta especificada
$path
. La ruta puede ser una cadena o una matriz. Consiste en los nombres de las claves de la matriz de entrada y
operadores como ‘[]’, ‘->’, ‘=’ y ‘|’. Lanza Nette\InvalidArgumentException
si la ruta no es
válida.
// conversión a array asociativo utilizando una clave simple
$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]]
// asignar valores de una clave a otra mediante el operador =
$result = Arrays::associate($arr, 'name=age'); // o ['name', '=', 'age']
// $result = ['John' => 11, 'Mary' => null, ...]
// crear un objeto utilizando el operador ->
$result = Arrays::associate($arr, '->name'); // o ['->', 'name']
// $result = (object) ['John' => ['name' => 'John', 'age' => 11], 'Mary' => ['name' => 'Mary', 'age' => null]]
// combinación de claves mediante el operador |
$result = Arrays::associate($arr, 'name|age'); // o ['name', '|', 'age']
// $result: ['John' => ['name' => 'John', 'age' => 11], 'Paul' => ['name' => 'Paul', 'age' => 44]]
// añadir a un array usando []
$result = Arrays::associate($arr, 'name[]'); // o ['name', '[]']
// $result: ['John' => [['name' => 'John', 'age' => 22], ['name' => 'John', 'age' => 11]]]
contains (array $array, $value): bool
Comprueba la presencia de un valor en un array. Utiliza una comparación estricta (===
)
Arrays::contains([1, 2, 3], 1); // true
Arrays::contains(['1', false], 1); // false
every (array $array, callable $predicate): bool
Comprueba si todos los elementos de la matriz pasan la prueba implementada por la función proporcionada, que tiene la firma
function ($value, $key, array $array): bool
.
$array = [1, 30, 39, 29, 10, 13];
$isBelowThreshold = fn($value) => $value < 40;
$res = Arrays::every($array, $isBelowThreshold); // true
Véase some().
filter (array $array, callable $predicate): array
Devuelve una nueva matriz que contiene todos los pares clave-valor que coinciden con la dirección $predicate
. La
llamada de retorno tiene la firma 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
Devuelve el primer elemento (que coincida con el predicado especificado si se da). Si no existe tal elemento, devuelve el
resultado de invocar $else
o null. El $predicate
tiene la firma
function ($value, int|string $key, array $array): bool
.
No modifica el puntero interno, a diferencia de reset()
. Los parámetros $predicate
y
$else
existen desde la versión 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
Véase last().
firstKey (array $array, ?callable $predicate=null): int|string|null
Devuelve la clave del primer elemento (que coincida con el predicado especificado si se da) o null si no existe tal elemento.
$predicate
tiene la firma 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
Véase lastKey().
flatten (array $array, bool $preserveKeys=false): array
Transforma array multidimensional a array plano.
$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
Devuelve $array[$key]
item. Si no existe, se lanza Nette\InvalidArgumentException
, a menos que se
establezca un valor por defecto como tercer argumento.
// if $array['foo'] does not exist, throws an exception
$value = Arrays::get($array, 'foo');
// if $array['foo'] does not exist, returns 'bar'
$value = Arrays::get($array, 'foo', 'bar');
El argumento $key
también puede ser una matriz.
$array = ['color' => ['favorite' => 'red'], 5];
$value = Arrays::get($array, ['color', 'favorite']);
// returns 'red'
getRef (array &$array, string|int|array $key): mixed
Obtiene la referencia a un $array[$key]
. Si el índice no existe, se crea uno nuevo con el valor
null
.
$valueRef = & Arrays::getRef($array, 'foo');
// returns $array['foo'] reference
Funciona con matrices multidimensionales así como con get().
$value = & Arrays::get($array, ['color', 'favorite']);
// returns $array['color']['favorite'] reference
grep (array $array, string $pattern, bool $invert=false): array
Devuelve sólo los elementos de la matriz que coinciden con una expresión regular $pattern
. En cambio, cuando
$invert = true
, devuelve elementos que no coinciden. Se produce un error de compilación o de ejecución de la
expresión regular Nette\RegexpException
.
$filteredArray = Arrays::grep($array, '~^\d+$~');
// returns only numerical items
insertAfter (array &$array, string|int|null $key, array $inserted): void
Inserta el contenido de la matriz $inserted
en $array
inmediatamente después de $key
.
Si $key
es null
(o no existe), se inserta al final.
$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
Inserta el contenido de la matriz $inserted
en $array
antes de $key
. Si
$key
es null
(o no existe), se inserta al principio.
$array = ['first' => 10, 'second' => 20];
Arrays::insertBefore($array, 'first', ['hello' => 'world']);
// $array = ['hello' => 'world', 'first' => 10, 'second' => 20];
invoke (iterable $callbacks, …$args): array
Invoca todos los callbacks y devuelve el array de resultados.
$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
Invoca el método en cada objeto de un array y devuelve un array de resultados.
$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
Comprueba si la matriz está indexada en orden ascendente de claves numéricas a partir de cero, es decir, si es una lista.
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
Devuelve el último elemento (que coincida con el predicado especificado si se da). Si no existe tal elemento, devuelve el
resultado de invocar $else
o null. El $predicate
tiene la firma
function ($value, int|string $key, array $array): bool
.
No modifica el puntero interno, a diferencia de end()
. Los parámetros $predicate
y
$else
existen desde la versión 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
Véase first().
lastKey (array $array, ?callable $predicate=null): int|string|null
Devuelve la clave del último elemento (que coincida con el predicado especificado si se da) o null si no existe tal elemento.
$predicate
tiene la firma 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
Véase firstKey().
map (array $array, callable $transformer): array
Llama a $transformer
en todos los elementos de la matriz y devuelve la matriz de valores de retorno. La llamada de
retorno tiene la firma 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
Crea un nuevo array transformando los valores y claves del array original. La función $transformer
tiene la firma
function ($value, $key, array $array): ?array{$newValue, $newKey}
. Si $transformer
devuelve
null
, el elemento se omite. Para los elementos retenidos, el primer elemento de la matriz devuelta se utiliza como la
nueva clave y el segundo elemento como el nuevo valor.
$array = ['a' => 1, 'b' => 2, 'c' => 3];
$result = Arrays::mapWithKeys($array, fn($v, $k) => $v > 1 ? [$v * 2, strtoupper($k)] : null);
// [4 => 'B']
Este método es útil en situaciones en las que se necesita cambiar la estructura de una matriz (tanto claves como valores simultáneamente) o filtrar elementos durante la transformación (devolviendo null para los elementos no deseados).
mergeTree (array $array1, array $array2): array
Fusiona recursivamente dos campos. Es útil, por ejemplo, para fusionar estructuras de árbol. Se comporta como el operador
+
para matrices, es decir, añade un par clave/valor de la segunda matriz a la primera y conserva el valor de la
primera matriz en caso de colisión de claves.
$array1 = ['color' => ['favorite' => 'red'], 5];
$array2 = [10, 'color' => ['favorite' => 'green', 'blue']];
$array = Arrays::mergeTree($array1, $array2);
// $array = ['color' => ['favorite' => 'red', 'blue'], 5];
Los valores de la segunda matriz se añaden siempre a la primera. La desaparición del valor 10
de la segunda
matriz puede parecer un poco confusa. Debe tenerse en cuenta que este valor, así como el valor 5
in the first array
have the same numeric key 0
, por lo que en el campo resultante sólo hay un elemento de la primera matriz.
normalize (array $array, ?string $filling=null): array
Normaliza array a array asociativo. Sustituye las claves numéricas por sus valores, el nuevo valor será
$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
Devuelve y elimina el valor de un elemento de un array. Si no existe, lanza una excepción, o devuelve $default
,
si se proporciona.
$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
Cambia el nombre de una clave. Devuelve true
si la clave se encontró en el array.
$array = ['first' => 10, 'second' => 20];
Arrays::renameKey($array, 'first', 'renamed');
// $array = ['renamed' => 10, 'second' => 20];
getKeyOffset (array $array, string|int $key): ?int
Devuelve la posición de índice cero de la clave del array dado. Devuelve null
si no se encuentra la clave.
$array = ['first' => 10, 'second' => 20];
$position = Arrays::getKeyOffset($array, 'first'); // returns 0
$position = Arrays::getKeyOffset($array, 'second'); // returns 1
$position = Arrays::getKeyOffset($array, 'not-exists'); // returns null
some (array $array, callable $predicate): bool
Comprueba si al menos un elemento de la matriz supera la prueba implementada por la llamada de retorno proporcionada con la
firma function ($value, $key, array $array): bool
.
$array = [1, 2, 3, 4];
$isEven = fn($value) => $value % 2 === 0;
$res = Arrays::some($array, $isEven); // true
Véase every().
toKey (mixed $key): string|int
Convierte un valor en una clave de matriz, que puede ser un entero o una cadena.
Arrays::toKey('1'); // 1
Arrays::toKey('01'); // '01'
toObject (iterable $array, object $object): object
Copia los elementos del array $array
al objeto $object
y luego lo devuelve.
$obj = new stdClass;
$array = ['foo' => 1, 'bar' => 2];
Arrays::toObject($array, $obj); // it sets $obj->foo = 1; $obj->bar = 2;
wrap (array $array, string
$prefix=''
, string $suffix=''
): array
Convierte cada elemento del array en cadena y lo encierra con $prefix
y $suffix
.
$array = Arrays::wrap(['a' => 'red', 'b' => 'green'], '<<', '>>');
// $array = ['a' => '<<red>>', 'b' => '<<green>>'];
ArrayHash
El objeto Nette\Utils\ArrayHash es el descendiente de la clase genérica stdClass y lo extiende a la capacidad de tratarlo como un array, por ejemplo, accediendo a los miembros usando corchetes:
$hash = new Nette\Utils\ArrayHash;
$hash['foo'] = 123;
$hash->bar = 456; // also works object notation
$hash->foo; // 123
Puedes utilizar la función count($hash)
para obtener el número de elementos.
Puedes iterar sobre un objeto como lo harías sobre un array, incluso con una referencia:
foreach ($hash as $key => $value) {
// ...
}
foreach ($hash as $key => &$value) {
$value = 'nuevo valor';
}
Las matrices existentes pueden transformarse a ArrayHash
utilizando from()
:
$array = ['foo' => 123, 'bar' => 456];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->foo; // 123
$hash->bar; // 456
La transformación es recursiva:
$array = ['foo' => 123, 'inner' => ['a' => 'b']];
$hash = Nette\Utils\ArrayHash::from($array);
$hash->inner; // object ArrayHash
$hash->inner->a; // 'b'
$hash['inner']['a']; // 'b'
Se puede evitar mediante el segundo parámetro:
$hash = Nette\Utils\ArrayHash::from($array, false);
$hash->inner; // array
Transformar de nuevo a la matriz:
$array = (array) $hash;
ArrayList
Nette\Utils\ArrayList representa un array lineal donde los índices son sólo enteros ascendentes desde 0.
$list = new Nette\Utils\ArrayList;
$list[] = 'a';
$list[] = 'b';
$list[] = 'c';
// ArrayList(0 => 'a', 1 => 'b', 2 => 'c')
count($list); // 3
Puede utilizar la función count($list)
para obtener el número de elementos.
Puedes iterar sobre un objeto como lo harías sobre un array, incluso con una referencia:
foreach ($list as $key => $value) {
// ...
}
foreach ($list as $key => &$value) {
$value = 'nuevo valor';
}
Las matrices existentes pueden transformarse a ArrayList
utilizando from()
:
$array = ['foo', 'bar'];
$list = Nette\Utils\ArrayList::from($array);
Acceder a claves más allá de los valores permitidos lanza una excepción Nette\OutOfRangeException
:
echo $list[-1]; // throws Nette\OutOfRangeException
unset($list[30]); // throws Nette\OutOfRangeException
Al eliminar la clave se renumeran los elementos:
unset($list[1]);
// ArrayList(0 => 'a', 1 => 'c')
Puede añadir un nuevo elemento al principio utilizando prepend()
:
$list->prepend('d');
// ArrayList(0 => 'd', 1 => 'a', 2 => 'c')