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')
versión: 4.0