En PHP, ¿existe una función que devuelve una matriz formada por el valor de una clave de una matriz de matrices asociativas?

StackOverflow https://stackoverflow.com//questions/10659875

Pregunta

Estoy seguro de que esta pregunta se ha hecho antes, mis disculpas por no encontrarla primero.

La matriz original:

[0] => Array
    (
        [categoryId] => 1
        [eventId] => 2
        [eventName] => 3
        [vendorName] => 4
    )

[1] => Array
    (
        [categoryId] => 5
        [eventId] => 6
        [eventName] => 7
        [vendorName] => 8
    )

[2] => Array
    (
        [categoryId] => 9
        [eventId] => 10
        [eventName] => 11
        [vendorName] => 12
    )

Mi resultado esperado de:print_r(get_values_from_a_key_in_arrays('categoryId', $array));

[0] => 1
[1] => 5
[2] => 9

Solo estoy buscando algo más limpio que escribir mi propia función basada en foreach.Si foreach es la respuesta, ya la tengo implementada.

Editar: No quiero usar una clave codificada, solo estaba mostrando una llamada de ejemplo a la solución.¡Gracias!^_^

Solución de agarre rápido para PHP 5.3:

private function pluck($key, $data) {
    return array_reduce($data, function($result, $array) use($key) {
        isset($array[$key]) && $result[] = $array[$key];
        return $result;
    }, array());
}
¿Fue útil?

Solución

Entonces, lo bueno de orden superior funciones de colección/iterador como arrancar, filtrar, cada, mapa, y amigos es que se pueden mezclar y combinar para componer un conjunto de operaciones más complejo.

La mayoría de los lenguajes proporcionan este tipo de funciones (busque paquetes como colección, iterador o enumeración/enumerable)... algunos proporcionan más funciones que otros y comúnmente verá que las funciones tienen nombres diferentes entre los idiomas (es decir,recopilar == mapa, reducir == doblar).Si una función no existe en tu idioma, puedes crearlo de los que existen.

En cuanto a su caso de prueba... podemos usar matriz_reducir para implementar arrancar.La primera versión que publiqué se basó en array_map;sin embargo, estoy de acuerdo con @salathe eso matriz_reducir es más conciso para esta tarea; mapa_matriz es una buena opción, pero al final tendrás que trabajar más. array_reduce Puede parecer un poco extraño al principio, pero si la devolución de llamada está bien organizada, todo estará bien.

Un menos ingenuo pluck También verificaría si puede "llamar" (una función/método) en el valor iterado.En la implementación ingenua siguiente, asumimos que la estructura es un hash (matriz asociativa).

Esto configurará los datos del caso de prueba (Accesorios):

<?php

$data[] = array('categoryId' => 1,    'eventId' => 2,  'eventName' => 3,  'vendorName' => 4);
$data[] = array('categoryId' => 5,    'eventId' => 6,  'eventName' => 7,  'vendorName' => 8);
$data[] = array('categoryId' => 9,    'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array(/* no categoryId */   'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array('categoryId' => false,'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);
$data[] = array('categoryId' => 0.0,  'eventId' => 10, 'eventName' => 11, 'vendorName' => 12);

Elige la versión de pluck que prefieras

$preferredPluck = 'pluck_array_reduce'; // or pluck_array_map

"arrancar" para PHP 5.3+:array_reduce proporciona una implementación concisa, aunque no es tan fácil de razonar como la versión array_map:

function pluck_array_reduce($key, $data) {
  return array_reduce($data, function($result, $array) use($key){
    isset($array[$key]) &&
      $result[] = $array[$key];

    return $result;
  }, array());
}

"arrancar" para PHP 5.3+:array_map no es perfecto para esto, por lo que tenemos que realizar más comprobaciones (y todavía no tiene en cuenta muchos casos potenciales):

function pluck_array_map($key, $data) {
  $map = array_map(function($array) use($key){
    return isset($array[$key]) ? $array[$key] : null;
  }, $data);

  // is_scalar isn't perfect; to make this right for you, you may have to adjust
  return array_filter($map, 'is_scalar');
}

"arrancar" para PHP heredado <5.3

Podríamos haber usado el legado crear_función;sin embargo, es de mala forma, no es recomendable y además nada elegante, por lo que he decidido no mostrarlo.

function pluck_compat($key, $data) {
  $map = array();
  foreach ($data as $array) {
    if (array_key_exists($key, $array)) {
      $map[] = $array[$key];
    }
  }
  unset($array);

  return $map;
}

Aquí elegimos una versión de "pluck" para llamar según la versión de PHP que estemos ejecutando.Si ejecuta el script completo, debería obtener la respuesta correcta sin importar en qué versión se encuentre.

$actual   = version_compare(PHP_VERSION, '5.3.0', '>=')
          ? $preferredPluck('categoryId', $data)
          : pluck_compat('categoryId', $data);
$expected = array(1, 5, 9, false, 0.0);
$variance = count(array_diff($expected, $actual));

var_dump($expected, $actual);
echo PHP_EOL;
echo 'variance: ', $variance, PHP_EOL;

print @assert($variance)
    ? 'Assertion Failed'
    : 'Assertion Passed';

Observe que no hay final '?>'.Eso es porque no es necesario.Puede resultar más beneficioso dejarlo que mantenerlo.

FWIW, parece que esto se está agregando a PHP 5.5 como columna_matriz.

Otros consejos

Mapeo es lo que necesita:

$input = array(
    array(
        'categoryId' => 1,
        'eventId' => 2,
        'eventName' => 3,
        'vendorName' => 4,
    ),
    array(
        'categoryId' => 5,
        'eventId' => 6,
        'eventName' => 7,
        'vendorName' => 8,
    ),
    array(
        'categoryId' => 9,
        'eventId' => 10,
        'eventName' => 11,
        'vendorName' => 12,
    ),
);

$result = array_map(function($val){
    return $val['categoryId'];
}, $input);

o creando una función que desea:

function get_values_from_a_key_in_arrays($key, $input){
    return array_map(function($val) use ($key) {
        return $val[$key];
    }, $input);
};

y luego usándolo:

$result = get_values_from_a_key_in_arrays('categoryId', $array);

Funcionará en PHP>= 5.3, donde se permiten devoluciones de llamada anónimas.Para versiones anteriores, deberá definir la devolución de llamada anterior y pasar su nombre en lugar de la función anónima.

No hay una función incorporada para esto, pero generalmente se refiere como " aruck ".

<?php
$a = array(
        array('a' => 1, 'b' => 2),
        array('a' => 2, 'b' => 2),
        array('a' => 3, 'b' => 2),
        array('a' => 4, 'b' => 2)
);

function get_a($v) {
        return $v['a'];
}

var_dump(array_map('get_a', $a));

Puede usar una función Create_Function o una función anónima (PHP 5.3>=)

<?php
$a = array(
        array('a' => 1, 'b' => 2),
        array('a' => 2, 'b' => 2),
        array('a' => 3, 'b' => 2),
        array('a' => 4, 'b' => 2)
);

var_dump(array_map(create_function('$v', 'return $v["a"];'), $a));

Escribiría una función de devolución de llamada, como se arriba, y luego usarlo con Array_Map.

No hay función incorporada.Pero uno se hace fácilmente con array_map().

$array = array(
    array(
        "categoryID"   => 1,
        "CategoryName" => 2,
        "EventName"    => 3,
        "VendorName"   => 4
    ),
    array(
        "categoryID"   => 5,
        "CategoryName" => 6,
        "EventName"    => 7,
        "VendorName"   => 8
    ),
    array(
        "categoryID"   => 9,
        "CategoryName" => 10,
        "EventName"    => 11,
        "VendorName"   => 12
    )
);

$newArray = array_map(function($el) {
    return $el["categoryID"];
}, $array);

var_dump($newArray);

¿Dónde está Lisp cuando lo necesitas?En realidad, en PHP, es bastante fácil de administrar también.Simplemente use la función Array_Map como se ilustra a continuación.

# bunch o data
$data = array();
$data[0] = array("id" => 100, "name" => 'ted');
$data[1] = array("id" => 200, "name" => 'mac');
$data[2] = array("id" => 204, "name" => 'bub');

# what you want to do to each bit of it
function pick($n) { return($n['id']); }
# what you get after you do that
$map = array_map("pick", $data);
# see for yourself
print_r($map);

ASO de PHP 5.5, use array_column :

$events = [
    [ 'categoryId' => 1, 'eventId' =>  2, 'eventName' =>  3, 'vendorName' =>  4 ],
    [ 'categoryId' => 5, 'eventId' =>  6, 'eventName' =>  7, 'vendorName' =>  8 ],
    [ 'categoryId' => 9, 'eventId' => 10, 'eventName' => 11, 'vendorName' => 12 ],
];

print_r(array_column($events, 'categoryId'));

Véalo en línea en 3V4L.

Para versiones antes de 5.5, puede considerar usar un PolyFill .

Podría usar array_filter y pasa en una funciónbasado en la clave deseada.

La respuesta de Tadeck es mucho mejor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top