пребройте броя на ключовете, които съпоставят стойност

Имам следния хеш

my %hash = (
    w1 => '0',
    e2 => '1',
    r1 => '2',
    o3 => '1',
    h4 => '0',
    t5 => '1',
);

Бих искал да получа броя на ключовете, които съответстват на всяка стойност в хеша.

3 keys map to value 1.
1 key map to value 2.
2 keys map to value 0.

Бих искал да направя това, без да използвам функция от модул.

Един от начините, по които се сетих да направя това, беше да премина през стойностите на хеша. Ако тази стойност има ключ, увеличете брояча за този ключ. Проблемът е да знам какви са стойностите предварително, за да мога да инициализирам броячи за всяка стойност. Вероятно има по-лесно решение за това. Мисля, че регулярният израз може да работи.

опит 1

my $string;
foreach my $value (value %hash) {
$string = join(",", $value);
}

# count the number of occurrences for each value (separated by commas)

person cooldood3490    schedule 19.04.2013    source източник


Отговори (2)


Използвайте друг хеш, за да преброите срещанията.

#!/usr/bin/perl
use warnings;
use strict;

my %hash = (
    w1 => '0',
    e2 => '1',
    r1 => '2',
    o3 => '1',
    h4 => '0',
    t5 => '1',
);

my %count;
for my $value (values %hash) {
    $count{$value}++;
}

for my $value (keys %count) {
    my $count = $count{$value};

    print "$count key", $count == 1 ? q() : 's',
          " map",       $count == 1 ? 's' : q(),
          " to $value.\n";
}
person choroba    schedule 19.04.2013
comment
можете ли да обясните синтаксиса в израза за печат? Например какво е ? и q() и 's'? За какво е :? - person cooldood3490; 20.04.2013
comment
q() е празен низ. condition ? true : false е троичен оператор, ако условието е вярно, то връща истинската част, в противен случай грешната част. В този случай се справя с граматиката. - person choroba; 20.04.2013

Можете да преминете през хеша:

my %counterhash = ();

while ( ($key, $value) = each %hash )
{
  #print "key: $key, value: $hash{$key}\n";
  $counterhash{$value}++;
}

След това counterhash ще бъде хеш на всяка стойност спрямо броя на срещанията на тази стойност

Не е нужно да инициализирате ключ за всеки отделен $value. Първоначално е недефиниран, но се интерпретира като нула, когато се увеличи.

В документацията се казва:

Единствените неща, които трябва да декларирате в Perl, са форматите на отчетите и подпрограмите (а понякога дори не и подпрограмите). Променливата съдържа недефинираната стойност ("undef"), докато не й бъде присвоена дефинирана стойност, която е нещо различно от "undef". Когато се използва като число, "undef" се третира като 0; когато се използва като низ, той се третира като празен низ, ""; и когато се използва като препратка, към която не се присвоява, се третира като грешка.

person ronalchn    schedule 19.04.2013
comment
това също работи. можете ли да покажете как бихте инициализирали $key и $value? Когато правя while ( my ($key, $value) = each %hash) {...}, това не работи за мен. Получавам синтактични грешки. - person cooldood3490; 20.04.2013
comment
не съм сигурен, копирах го от perlhowto.com/iterate_through_a_hash, защото всъщност не програмирам на perl , така че не съм запознат със синтаксиса - person ronalchn; 20.04.2013
comment
LOL добре в крайна сметка ти публикува решение, което работи! +1, сигурен съм, че идват още точки - person cooldood3490; 20.04.2013