2012-04-17 10 views
5

Ho una matrice semplice con i nomi al suo interno e voglio essere in grado di stampare facilmente il numero di volte che ogni nome appare.perl: conta gli elementi univoci nell'array

Ho provato a fare un sacco di cicli for per le istruzioni diff per creare prima un altro array con valori univoci, cercando di contare i valori nell'array dell'orinale e memorizzarli in un terzo array. Sembrava eccessivamente complesso e volevo vedere se forse esistesse un modo molto più semplice per farlo.

risposta

13

Utilizzare un hash per contare il numero di volte in cui ogni nome si verifica:

use warnings; 
use strict; 
use Data::Dumper; 
$Data::Dumper::Sortkeys=1; 

my @names = qw(bob mike joe bob); 
my %counts; 
$counts{$_}++ for @names; 
print Dumper(\%counts); 

__END__ 

$VAR1 = { 
      'bob' => 2, 
      'joe' => 1, 
      'mike' => 1 
     }; 
3

Il modo più semplice per farlo è quello di approfittare di hash.

my @names = qw/joe bob sue bob mike sally mike bob sally dale joe/; 
my %counts; 
$counts{$_}++ for @names; 

Questo vi darà un hash che assomiglia:

 'dale' => 1, 
     'sue' => 1, 
     'joe' => 2, 
     'mike' => 2, 
     'bob' => 3, 
     'sally' => 2 
4
my %counts; 
++$counts{$_} for @names; 
my @unique = keys(%counts); 

può essere accorciato per

my %counts; 
my @unique = grep !$counts{$_}++, @names; 

L'ex perde l'ordine dei nomi, mentre la seconda ha il vantaggio di preservare l'ordine. (Conserva il primo dei duplicati)

Quest'ultimo è anche un modo idiomatico di ottenere membri univoci di un elenco. Normalmente, il numero di conteggi è solo un effetto collaterale, ma in questo è un prodotto desiderato. :)

+0

grazie, nella mia situazione L'ordine non importa molto ma potrei aver bisogno di questo in futuro – searayman

Problemi correlati