Как найти, посчитать и отобразить уникальные элементы массива с помощью Perl? - PullRequest
0 голосов
/ 12 мая 2010

Я начинающий программист Perl и хотел бы помочь. У меня есть список массивов, который я пытаюсь разделить каждый элемент на основе канала на два скалярных элемента. Оттуда я хотел бы выделить только строки, которые читают «PJ RER Apts to Share» в качестве первого элемента. Затем я хочу распечатать второй элемент только один раз при подсчете каждый раз, когда элемент появляется. Я написал фрагмент кода ниже, но не могу понять, где я ошибаюсь. Это может быть что-то маленькое, что я просто пропускаю. Любая помощь будет принята с благодарностью.

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

Ответы [ 4 ]

3 голосов
/ 12 мая 2010

Вы можете использовать функцию uniq в List :: MoreUtils , чтобы удалить повторяющиеся записи из списка. Количество элементов в списке или массиве может быть легко найдено путем оценки списка в скалярном контексте:

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
3 голосов
/ 12 мая 2010

Это очень грубо, но я бы использовал потрясающие хеш-массивы Perl, чтобы помочь с этой задачей. Я бы взял всю запись и использовал ее для индексации хеш-массива и приращения к значению.

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

Когда это будет сделано, прокрутите ваш хэш-массив, и вы получите уникальные и повторяющиеся записи, которые будут отсчитываться от счетчика приращений.

Как я уже сказал, это очень грубо, и я уверен, что есть много проблем с подходом. Все вы, боги Perl, увольняетесь.

2 голосов
/ 12 мая 2010

Я использовал следующий скрипт:

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";
   }
}

И это дало:

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

Это то, что вы искали?

0 голосов
/ 12 мая 2010

Суммируйте количество вхождений на город в хэше. Ключом будет название города, а значением будет количество. Затем сортируйте ключи и выводите их и соответствующие им значения:

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"; 

Кроме того, вы хотите подсчитать все списки или только те, которые вы хотите соответствовать Если это позднее, измените следующую за последней строкой на:

$count = keys %apts;
...