2009-09-29 13 views
14

Tengo una matriz de matrices, con la siguiente estructura:¿Hay una función para extraer una 'columna' de una matriz en PHP?

array(array('page' => 'page1', 'name' => 'pagename1') 
     array('page' => 'page2', 'name' => 'pagename2') 
     array('page' => 'page3', 'name' => 'pagename3')) 

¿Hay una función incorporada que devolverá una nueva matriz con sólo los valores de las claves 'nombre'? entonces obtendría:

array('pagename1', 'pagename2', 'pagename3') 
+1

¿24 horas? De manera prematura. Espera 48 horas. Eso es bueno para permitir que algunas de las respuestas acumulen más votos y la abre para obtener un par de respuestas más relevantes. – random

+0

No quiero sonar como un idiota, pero esta no es una pregunta complicada que en unos días revelará una solución increíble. – fuentesjr

Respuesta

17

¿Por qué tiene que ser una función incorporada? No, no hay ninguno, escribe el tuyo.

Aquí hay uno agradable y fácil, a diferencia de otros en este hilo.

$namearray = array(); 

foreach ($array as $item) { 
    $namearray[] = $item['name']; 
} 
+1

Bien, dada su edición reciente ('fácil, como opuesto a los demás) Voy a morder;) Si convierte su código en una función real según la solicitud original, será casi tan 'complejo' como los ejemplos 'array_map()' o 'array_walk()' a continuación, especialmente si desea agregar un ejemplo de ejecución. –

+0

Sí, creo que la mía es la más elegante de las funciones de PHP y el primer ejemplo completo. :) – fuentesjr

+1

Hola, gracias. Todo lo que realmente pregunté en mi pregunta fue si hay una función incorporada; no me gusta reinventar la rueda. Me diste una respuesta a eso, y tu solución es básicamente lo que yo habría escrito. – Skilldrick

-1

¿Quiere decir array_values?

Editar: Gracias por el voto negativo sin comentarios. Si alguien se hubiera tomado el tiempo de mirar la documentación de la función, habría visto el primer comentario que da un ejemplo de cómo escribir su propia función array_values_recursive. Combina eso con un array_walk y tendrías una función bastante ingeniosa que no tendría la columna 'nombre' codificada en ella. Sheesh.

+0

Lo voté de nuevo, pero ¿realmente esto se ha convertido en una competencia para encontrar la solución más compleja? :) –

+0

Gracias. :) Espero que esto no sea una competencia, solo un poco molesto de que esto suceda mucho cuando trato de dirigir a la gente en una dirección en lugar de escribir la solución para ellos. –

12

Aquí está una manera funcional de hacerlo:

$data = array(
      array('page' => 'page1', 'name' => 'pagename1'), 
      array('page' => 'page2', 'name' => 'pagename2'), 
      array('page' => 'page3', 'name' => 'pagename3')); 

$result = array_map(create_function('$arr', 'return $arr["name"];'), $data); 
print_r($result); 
+1

Me gusta esto, y la lambda encaja muy bien con mi cerebro en este momento, como he estado aprendiendo Scheme. +1 – Skilldrick

1

similares a la solución fuentesjrs, pero un poco más genérico utilizando array_walk() con una devolución de llamada personalizado:

// Define the callback 
function extract_named_sub_elements(&$item, $key, $name) { 
    $item = $item[$name]; 
} 

// Test data 
$original = array(
    array('page' => 'page1', 'name' => 'pagename1'), 
    array('page' => 'page2', 'name' => 'pagename2'), 
    array('page' => 'page3', 'name' => 'pagename3'), 
); 

// Use a copy, as array_walk() operates directly on the passed in array 
$copy = $original; 

// Substitute 'name' with whatever element you want to extract, e.g. 'page' 
array_walk($copy, 'extract_named_sub_elements', 'name'); 

print_r($copy); 
0

Puede extienda el ArrayIterator class y anule el método mixed current(void).

class Foo extends ArrayIterator { 
    protected $index; 
    public function __construct($array, $index) { 
    parent::__construct($array); 
    $this->index = $index; 
    } 

    public function current() { 
    $c = parent::current(); 
    return isset($c[$this->index]) ? $c[$this->index] : null; 
    } 
} 

$a = array(
    array('page' => 'page1', 'name' => 'pagename1'), 
    array('name' => '---'), 
    array('page' => 'page2', 'name' => 'pagename2'), 
    array('page' => 'page3', 'name' => 'pagename3') 
); 

$f = new Foo($a, 'page'); 
foreach($f as $e) { 
    echo $e, "\n"; 
} 

impresiones

page1 

page2 
page3 
0

No creo que haya ninguna necesidad de tener una función integrada para esto. Puede haber una matriz en su matriz.

$samples=array(
      array('page' => 'page1', 'name' => 'pagename1'), 
      array('page' => 'page2', 'name' => 'pagename2'), 
      array('page' => 'page3', 'name' => 'pagename3') 
      ); 

$output1=array(); 
$output2=array(); 
foreach($samples as $sample){ 
    array_push($output1,$sample['name']); 
    $output2[]=array_splice($sample,1); 

} 

print_r($output1); 
print_r($output2); 

en $ salida 1 es la salida de lo que quieres si sólo desea eliminar la parte 'página' indexación', entonces $ output2.

si necesita todos los valores de la matriz y los índices que numéricamente la matriz, puede utilizar

$array_1=array_values($samples); 

pero lo que entiendo, usted no quiere esto.

49

A partir de PHP 5.5 puede utilizar array_column():

<?php 
$samples=array(
      array('page' => 'page1', 'name' => 'pagename1'), 
      array('page' => 'page2', 'name' => 'pagename2'), 
      array('page' => 'page3', 'name' => 'pagename3') 
      ); 
$names = array_column($samples, 'name'); 
print_r($names); 

See it in action

+0

Bien, gracias John. He estado investigando en PHP 5.5, pero no había visto esto –

+10

Esta debería ser la respuesta correcta hasta ahora, ya que php ha agregado la función incorporada que es exactamente lo que el OP está pidiendo. – MJoraid

1
if (!function_exists('array_column')) { 
    function array_column($array,$column) { 
    $col = array(); 
    foreach ($array as $k => $v) { 
     $col[]=$v[$column]; 
    } 
    return $col; 
    } 
} 

Esto debería funcionar para las versiones de PHP < 5.5 y degradar en caso de que la función existe

4

Bueno hay. Al menos para PHP> 5.5.0 y se llama array_column

La función de PHP toma un parámetro opcional $index_key que - según el sitio web de PHP - afirma:

$index_key

La columna de usar como los índices/llaves para el matriz devuelta Este valor puede ser la clave entera de la columna, o puede ser el nombre clave de cadena

En las respuestas aquí, veo una versión simplificada sin el parámetro opcional. lo necesitaba, así que, aquí es la función completa:

if (!function_exists('array_column')) { 
    function array_column($array, $column, $index_key = null) { 
     $toret = array(); 
     foreach ($array as $key => $value) { 
      if ($index_key === null){ 
       $toret[] = $value[$column]; 
      }else{ 
       $toret[$value[$index_key]] = $value[$column]; 
      } 
     } 
     return $toret; 
    } 
} 
1

Sí, no es un PHP función integrada llamada array_column el que hace lo que usted está buscando.

Lo llamaría algo así como $name_keys = array_column($array, 'name'); para obtener el resultado que está buscando.

favor remítase a la siguiente entrada en el manual de PHP para más detalles:

http://php.net/manual/en/function.array-column.php

+0

Gracias kguest para que sea una respuesta completa. – Dinesh

+1

Esta respuesta solo es válida si la versión de PHP es mayor que 5. – Dinesh

+0

Mayor que 5.5, para ser exactos. – cytsunny

0

Este es un llamado bastante fácil de array_reduce.

$valuesOnly = array_reduce($modelData, function ($carry, $item) { 
    return array_merge($carry, $item['id']); 
}, []); 
-1

Para ampliar algunas de las respuestas aquí, a partir de PHP 5.5, array_column es lo que desea.

Realmente tiene algunos usos posibles.

Usando la matriz de muestra a continuación, estas son las diferentes maneras de usar array_column.

$a = array(
    array('id' => '1', 'name' => 'Joe'), 
    array('id' => '2', 'name' => 'Jane') 
); 

Recuperando una sola columna como la matriz

$b = array_column($a, 'name'); 

¿Quieres que dar. Observe las teclas automáticas comenzando desde 0, según una matriz normal.

$b[0] = 'Joe'; 
$b[1] = 'Jane'; 

Recuperando la matriz completa con una columna como índice.

$c = array_column($a, NULL, 'id'); 

Resultará en lo siguiente.

$c[1] = array('id' => '1', 'name' => 'Joe'); 
$c[2] = array('id' => '2', 'name' => 'Jane'); 

Observe cómo la columna que he seleccionado como tercer parámetro se convierte en la clave para cada elemento y tengo la gama completa estableciendo el segundo parámetro en null.

Por supuesto, el uso final es establecer tanto el 2 ° como el 3 ° params.

$d = array_column($a, 'name', 'id'); 

Te daría lo siguiente.

$d[1] = 'Joe'; 
$d[2] = 'Jane'; 

Yo personalmente uso los 3 parámetros completos para crear listas de opciones de selección.Si tengo una tabla con mis opciones, consulto la tabla y obtengo el resultado y lo paso a esto para obtener una lista con la clave como el valor y la etiqueta. Esta es una manera brillante de crear conjuntos de información que también deben cruzarse por el índice.

0

Yo quería publicar aquí, incluso si se trata de una cuestión de edad, ya que sigue siendo muy relevante y muchos desarrolladores no utilizan PHP> = 5.5

Digamos que tiene una matriz de esta manera:

Array 
(
    [files] => Array 
     (
      [name] => Array 
       (
        [0] => file 1 
        [1] => file 2 
        [2] => file 3 
       ) 

      [size] => Array 
       (
        [0] => 1 
        [1] => 2 
        [2] => 3 
       ) 

      [error] => Array 
       (
        [0] => abc 
        [1] => def 
        [2] => ghi 
       ) 

     ) 

) 

y la salida que desea es algo como esto:

Array 
(
    [0] => Array 
     (
      [0] => file 1 
      [1] => 1 
      [2] => abc 
     ) 

    [1] => Array 
     (
      [0] => file 2 
      [1] => 2 
      [2] => def 
     ) 

    [2] => Array 
     (
      [0] => file 3 
      [1] => 3 
      [2] => ghi 
     ) 

) 

usted puede simplemente utilizar el método array_map() sin un nombre de función pasada como primer parámetro, así:

array_map(null, $a['files']['name'], $a['files']['size'], $a['files']['error']); 

Desafortunadamente no puede asignar las teclas si pasa más de una matriz.

Cuestiones relacionadas