2010-05-12 3 views
0

Je suis un programmeur Perl débutant et je voudrais de l'aide. J'ai une liste de tableau que j'essaye de diviser chaque élément basé sur le tuyau en deux éléments scalaires. De là, je voudrais pointer uniquement les lignes qui lisent 'PJ RER Apts to Share' comme premier élément. Ensuite, je veux imprimer le deuxième élément une seule fois en comptant chaque fois que l'élément apparaît. J'ai écrit le code ci-dessous, mais je n'arrive pas à comprendre où je me trompe. Ce pourrait être quelque chose de petit que je ne fais que négliger. Toute aide serait grandement appréciée.Comment rechercher, compter et afficher des éléments uniques d'un tableau à l'aide de Perl?

## CODE ## 

my @data = ('PJ RER Apts to Share|PROVIDENCE', 
     'PJ RER Apts to Share|JOHNSTON', 
     'PJ RER Apts to Share|JOHNSTON', 
     'PJ RER Apts to Share|JOHNSTON', 
     'PJ RER Condo|WEST WARWICK', 
     'PJ RER Condo|WARWICK'); 

foreach my $line (@data) { 
    $count = @data; 
    chomp($line); 
    @fields = split(/\|/,$line); 
    if (($fields[0] =~ /PJ RER Apts to Share/g)){ 
     @array2 = $fields[1]; 
     my %seen; 
     my @uniq = grep { ! $seen{$_}++ } @array2; 
     my $count2 = scalar(@uniq); 
     print "$array2[0] ($count2)","\n" 
    } 
} 
print "$count","\n"; 

## OUTPUT ## 

PROVIDENCE (1) 
JOHNSTON (1) 
JOHNSTON (1) 
JOHNSTON (1) 
6 

Répondre

2

J'ai utilisé le script suivant:

my %elements = (); 

foreach (@data) { 
    chomp; 
    my ($f0, $f1) = split(/\|/); 
    $elements{ $f0 }{ $f1 }++; 
} 

while (my ($k, $v) = each(%elements)) 
{ 
    print "Key [$k] :\n"; 
    while (my ($field2, $count) = each(%$v)) 
    { 
     print " Field [$field2] appeared $count times\n"; 
    } 
} 

Et il a abouti:

Key [PJ RER Condo] : 
    Field [WARWICK] appeared 1 times 
    Field [WEST WARWICK] appeared 1 times 
Key [PJ RER Apts to Share] : 
    Field [JOHNSTON] appeared 3 times 
    Field [PROVIDENCE] appeared 1 times 

Est-ce que vous cherchez?

+0

Est-ce que ce tri les champs ou il recrache les données dans un ordre aléatoire? – Luke

+0

Si vous voulez trier, alors dites 'each (sort% $ v)' dans la dernière boucle 'while'. J'espère que cela aide! – Phil

3

Ceci est très brut, mais j'utiliser des tableaux de hachage impressionnants de Perl pour aider à cette tâche. Je prendrais l'enregistrement entier et l'emploierais pour indexer le tableau de hachage et un incrément à la valeur.

foreach (@array) { 
    $myHash{$_}++; 
} 

Une fois terminé, faire défiler votre tableau de hachage et vous aurez unique et les enregistrements en double aussi bien comptés à partir du compteur d'incrément. Comme je l'ai dit, c'est très grossier et je suis sûr qu'il y a beaucoup de problèmes avec cette approche. Tous les dieux de Perl s'enflamment.

+7

Ce n'est pas grossier du tout, c'est la manière correcte et idiomatique de le faire. – friedo

3

Vous pouvez utiliser la fonction uniq dans List::MoreUtils pour supprimer les entrées en double d'une liste. Le nombre d'éléments dans une liste ou un tableau peut être facilement trouvé en évaluant la liste dans un contexte scalaire:

use strict; use warnings; 
use List::MoreUtils 'uniq'; 
my @list = qw(1 1 2 3 5 8); 

my @uniq = uniq @list; 
print 'list with dupes removed: ', join(', ', @uniq), "\n"; 
print 'number of elements in this list: ', scalar(@uniq), "\n"; 
 
list with dupes removed: 1, 2, 3, 5, 8 
number of elements in this list: 5 
0

Accumulez le nombre d'occurrence par ville, dans un hachage. La clé sera le nom de la ville et la valeur sera le nombre. Ensuite, trier les clés et les sortir et les valeurs correspondantes:

my @data = ('PJ RER Apts to Share|PROVIDENCE', 
    'PJ RER Apts to Share|JOHNSTON', 
    'PJ RER Apts to Share|JOHNSTON', 
    'PJ RER Apts to Share|JOHNSTON', 
    'PJ RER Condo|WEST WARWICK', 
    'PJ RER Condo|WARWICK'); 

foreach my $line (@data) { 
    chomp($line); 
    @fields = split(/\|/,$line); 
    if ($fields[0] eq "PJ RER Apts to Share"){ 
     $city = "\u\L$fields[1]"; 
     $apts{$city}++; 

    } 
} 

@city_sort = sort (@city); 
print map {"$_ $apts{$_}\n";} sort(keys %apts); 
$count = @data; 
print "$count","\n"; 

Aussi, avez-vous un compte de toutes les annonces ou tout simplement ceux que vous voulez faire correspondre. Si c'est le changement plus tard le prochain à la dernière ligne à:

$count = keys %apts; 
Questions connexes