2010-06-15 17 views
7

Diciamo che in Perl ho una lista di riferimenti hash, e ognuno è necessario per contenere un certo campo, diciamo foo. Voglio creare un elenco che contenga tutti i mapping di foo. Se c'è un hash che non contiene foo il processo dovrebbe fallire.Perl, ottieni tutti i valori hash

@hash_list = (
{foo=>1}, 
{foo=>2} 
); 

my @list =(); 
foreach my $item (@hash_list) { 
    push(@list,$item->{foo}); 
} 

#list should be (1,2); 

C'è un modo più conciso di farlo in Perl?

+1

Volevo solo chiarire che non stai creando un elenco di mapping, stai creando un elenco costituito da ciascun valore di hash 'foo'. E il tuo esempio di codice non ha nulla a che fare con il 'processo fallito' in modo da Non solo chiedendo più conciso. –

+1

In generale: ogni volta che ti trovi a fare 'foreach ... {... push ..}' puoi rendere il codice più breve e più semplice usando map o grep. – Ether

risposta

6

Sì. c'è.

my @list = map { 
    exists $_->{foo} ? $_->{foo} : die 'hashed lacked foo' 
    } 
    @hash_list 
; 
+0

per espressioni di mappe complesse come questa, di solito è più facile da leggere usando la sintassi del blocco piuttosto che l'espressione nuda –

+0

che è meglio +1, io uso sempre la sintassi nuda per le espressioni corte, probabilmente l'unica lunga che non ottenere un blocco è il caso di una mappa che restituisce un arrayref: 'map [...] => ...' –

0
if (@hash_list != grep { exists $_->{foo} } @hash_list) { 
    # test failed 
} 
1

la risposta di Evan è vicino, ma restituirà i hashrefs piuttosto che il valore di foo.

my @list = map $_->{foo} grep { exists $_->{foo} } @hash_list 
+0

Sì, ho risolto questo. e, l'ho fatto anche morire, c'è una disconnessione tra il suo codice e la sua domanda. Puoi anche farlo con un ciclo. –

2

È possibile utilizzare la funzione di mappa per questo:

@hash_list = (
{foo=>1}, 
{foo=>2} 
); 

@list = map($_->{foo}, @hash_list); 

mappa si applica la funzione nel primo argomento su tutti gli elementi del secondo argomento.

grep è anche bello filtrare gli elementi in un elenco e funziona allo stesso modo.