Как посчитать дубликат ключа и сложить все значения дубликата ключа, чтобы создать новый хэш с неповторяющимся ключом? - PullRequest
1 голос
/ 12 ноября 2011

Привет, я новичок в Perl, и на начальном этапе. Пожалуйста, помогите. У меня хэш

%hash = { a => 2 , b=>6, a=>4, f=>2, b=>1, a=>1}

Я хочу вывод, как

  • a приходит 3 раза
  • b приходит 2 раза
  • f приходит 1 раз

новый хеш должен быть

%newhash = { a => 7, b=>7,f =>2}

Как я могу это сделать?

Для подсчета частоты ключей в хэше, которые я делаю

foreach $element(sort keys %hash) {
    my $count = grep /$element/, sort keys %hash;
    print "$element comes in $count times \n";
}

Но, делая это, я получаю вывод как:

a comes 1 times 
b comes 1 times 
a comes 1 times
f comes 1 times 
b comes 1 times
a comes 1 times

Что не то, чтоЯ хочу.

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

Ответы [ 2 ]

6 голосов
/ 12 ноября 2011

По определению, хэш не может иметь один и тот же ключ хеша несколько раз.Вы, вероятно, хотите сохранить свои исходные данные в другой структуре данных, такой как двумерный массив:

use strict;
use warnings;
use Data::Dumper;

my @data = ( [ a => 2 ], 
             [ b => 6 ],
             [ a => 4 ],
             [ f => 2 ], 
             [ b => 1 ],
             [ a => 1 ],
           );
my %results;

for my $value (@data) {
  $results{$value->[0]} += $value->[1];
}

print Dumper %results;

# $VAR1 = 'a';
# $VAR2 = 7;
# $VAR3 = 'b';
# $VAR4 = 7;
# $VAR5 = 'f';
# $VAR6 = 2;

Тем не менее, другие неправильные вещи:

%hash = { a => 2 , b=>6, a=>4, f=>2, b=>1, a=>1}

Вы можете 'Для этого он присваивает хэш-ссылку ({}) хешу.Либо используйте %hash = ( ... ) или $hashref = { ... }.

2 голосов
/ 12 ноября 2011

Сонам:

Я отредактировал ваш пост, чтобы помочь отформатировать его для чтения.Изучите Справочное руководство по редактированию Markdown , и это сделает ваши сообщения более понятными и понятными.Вот несколько советов:

  • Сделайте отступ в вашем коде четырьмя пробелами.Это говорит Markdown оставить его в покое и не переформатировать его.
  • Когда вы составляете список, поместите астрики с пробелом впереди.Markdown понимает, что это маркированный список, и форматирует его таким образом.

Нажмите «Изменить» в исходном сообщении, и вы увидите, какие изменения я внес.


Теперь нана ваш пост.Я не уверен, что понимаю ваши данные .Если бы ваши данные были в хэше, ключи были бы уникальными.Вы не можете иметь дубликаты ключей в хэше, так откуда же берутся ваши данные?

Например, если вы читаете их из файла с двумя числами в каждой строке, вы можете сделать это:

use autodie;
use strict;
use warnings;

open (my $data_fh, "<", "$fileName");
my %hash;
while (my $line = <$data_fh>) {
   chomp $line;
   my ($key, $value) = split /\s+/, $line;
   $hash{$key}++;
}
foreach my $key (sort keys %hash) {
    print "$key appears $hash{$key} times\n";
}

Первые три строки Perl pragmas .Они изменяют способ работы Perl:

  • use autodie: Это говорит программе о смерти в определенных обстоятельствах, например, при попытке открыть файл, который не существует.Таким образом, мне не нужно было проверять, работает ли оператор open или нет.
  • use strict: Это гарантирует, что вам придется объявлять переменные перед их использованием, что помогает исключить 90%Ошибки Perl.Вы объявляете переменную большую часть времени , используя my.Переменные, объявленные с my последними в блоке, где они были объявлены.Вот почему my %hash должно быть объявлено перед блоком while.В противном случае переменная станет неопределенной после завершения цикла.
  • use warnings: Perl генерирует предупреждения в определенных условиях.Например, вы пытаетесь распечатать переменную, для которой не задано пользовательское значение.

Первый цикл просто построчно просматривает мои данные и подсчитывает количество вхождений вашего ключа.Второй цикл выводит результаты.

...