2009-09-29 8 views
14

Ho un array di array, con la seguente struttura:Esiste una funzione per estrarre una "colonna" da una matrice in PHP?

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

C'è una funzione built-in che restituisce un nuovo array con solo i valori delle chiavi di 'nome'? quindi mi piacerebbe avere:

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

24 ore? Via prematura. Attendi 48 ore. Questo è buono per lasciare che alcune delle risposte accumulino più voti e la aprano per un paio di risposte più rilevanti. – random

+0

Non voglio sembrare uno stronzo, ma questa non è una domanda complicata che in pochi giorni rivelerà una soluzione sorprendente. – fuentesjr

risposta

17

Perché deve essere una funzione integrata? No, non c'è nessuno, scrivi il tuo.

Ecco una bella e facile, al contrario di altri in questa discussione.

$namearray = array(); 

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

Ok, data la tua modifica recente (' facile, come opposto ad altri ') Mi morderò;) Se trasformi il tuo codice in una funzione reale secondo la richiesta originale, sarà approssimativamente' complesso 'come gli esempi 'array_map()' o 'array_walk()' di seguito, soprattutto se ti piacerebbe aggiungere un esempio di esecuzione. –

+0

Sì, penso che il mio sia il più elegante dato le caratteristiche del PHP e il primo esempio completo. :) – fuentesjr

+1

Ciao, grazie. Tutto quello che ho chiesto nella mia domanda era se c'è una funzione built-in - non mi piace reinventare la ruota. Mi hai dato una risposta, e la tua soluzione è fondamentalmente ciò che avrei scritto. – Skilldrick

-1

Vuoi dire array_values?

Modifica: Grazie per il commento negativo. Se chiunque avesse avuto il tempo di esaminare effettivamente la documentazione per la funzione, avresti visto il primo commento che fornisce un esempio di scrittura della propria funzione array_values_recursive. Combinalo con un array_walk e avresti una bella funzione che non avrebbe la colonna 'name' codificata in esso. Sheesh.

+0

Ti ho votato di nuovo, ma è davvero diventato un concorso per trovare la soluzione più complessa? :) –

+0

Grazie. :) Speriamo che questa non sia una competizione, solo un po 'infastidito dal fatto che questo accada molto quando provo a guidare le persone in una direzione invece di scrivere la soluzione per loro .. –

12

Ecco un modo funzionale di farlo:

$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

Mi piace questo, e il lambda in esso si adatta bene al mio cervello in questo momento, poiché sto imparando Scheme. +1 – Skilldrick

1

Simile alla soluzione fuentesjrs, ma un po 'più generico utilizzando array_walk() con un callback personalizzato:

// 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

Puoi estendere ArrayIterator class e sovrascrivere il metodo 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"; 
} 

stampe

page1 

page2 
page3 
0

Non penso che ci sia alcun bisogno di avere una costruito in funzione di questo. Potrebbe esserci una matrice nella vostra matrice.

$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); 

a $ output1 è l'uscita ciò che si vuole, se si desidera rimuovere la parte 'pagina' indicizzazione' allora $ Output2.

se avete bisogno di tutti i valori dalla tale matrice e gli indici numericamente la matrice quindi è possibile utilizzare

$array_1=array_values($samples); 

ma quello che ho capito, non volevi questo.

49

Come di PHP 5.5 è possibile utilizzare 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

Bello, grazie Giovanni. Ho fatto ricerche su PHP 5.5, ma non avevo visto questo –

+10

Questa dovrebbe essere la risposta corretta ormai da quando php ha aggiunto la funzione incorporata che esattamente quello che l'OP sta chiedendo. – MJoraid

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

questo dovrebbe funzionare per le versioni di PHP < 5.5 e degradare nel caso in cui la funzione esiste

4

Beh c'è. Almeno per PHP> 5.5.0 e si chiama array_column

La funzione PHP prende un $index_key parametro opzionale che - secondo il sito web PHP - afferma:

$index_key

La colonna da utilizzare come l'indice/chiavi per la array restituito. Questo valore può essere la chiave intera della colonna, o può essere il nome della chiave di stringa

Nelle risposte qui, vedo in una versione ridotta, senza il parametro opzionale. ne avevo bisogno, quindi, qui è la funzione 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ì, c'è un php funzione built-in chiamato array_column che fa quello che si sta cercando.

Si potrebbe chiamare qualcosa come $name_keys = array_column($array, 'name'); per ottenere il risultato che si sta cercando.

Si prega di fare riferimento alla seguente voce nel manuale di PHP per maggiori dettagli:

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

+0

Grazie a kguest per renderlo una risposta completa. – Dinesh

+1

Questa risposta è valida solo se la versione di PHP è maggiore di 5. – Dinesh

+0

Maggiore di 5.5, per la precisione. – cytsunny

0

Questa è una chiamata abbastanza facile da array_reduce.

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

Solo per estendere su alcune delle risposte qui, a partire da PHP 5.5, array_column è ciò che si desidera.

In realtà ha alcuni possibili usi.

Utilizzando l'array campione sottostante, ecco i diversi modi di utilizzare array_column.

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

Recupero di una singola colonna come matrice

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

darebbe. Si noti che i tasti automatici iniziano da 0, come per un normale array.

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

Recupero dell'intero array con una colonna come indice.

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

Il risultato sarebbe il seguente.

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

Si noti come la colonna selezionato come terzo parametro diventa la chiave per ogni elemento e ho l'allineamento completo impostando il secondo parametro su null.

Ovviamente, l'utilizzo finale è impostare sia il 2 ° sia il 3 ° parametro.

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

Ti darebbe quanto segue.

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

Personalmente utilizzo tutti i 3 parametri per la creazione di elenchi di opzioni selezionate.Se ho una tabella con le mie opzioni, interrogo la tabella e ottengo il risultato e lo passo in questo per ottenere un elenco con la chiave come valore e l'etichetta. Questo è un modo geniale per costruire insiemi di informazioni che devono intersecarsi anche dall'indice.

0

volevo postare qui, anche se questa è una vecchia questione, perché è ancora molto rilevante e molti sviluppatori non utilizzano PHP> = 5.5

Supponiamo di avere un array come questo:

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 
       ) 

     ) 

) 

e l'uscita che si desidera è qualcosa di simile:

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 
     ) 

) 

si può semplicemente utilizzare il metodo array_map() senza un nome funzione passata come primo parametro, in questo modo:

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

Sfortunatamente non è possibile mappare i tasti se si passa più di un array.

Problemi correlati