1

对于 Perl 大师来说,这很容易......

我想要一个函数,它只接受一个项目数组(实际上是多个数组)并计算哈希键部分中每个项目存在的次数。但是,我真的不确定 Perl 哈希。

@array = qw/banana apple orange apple orange apple pear/

我读到你需要使用这样的代码来做数组:

my %hash = (
    'banana' => 0,
    'orange' => 0,
    'apple' => 0
    #I intentionally left out pear... I only want the values in the array...
);

但是,我正在努力让一个循环工作,该循环可以通过并将一个对应的键添加到值中,该键等于数组中每个项目的数组中的值。

foreach $fruit (@array) {
    if ($_ #is equal to a key in the hash) {
        #Add one to the corresponding value
    }
}

这包含了一些基本功能,所以代表所有初学者 Perl 程序员,提前谢谢你!

4

5 回答 5

6

所有你需要的是

my @array = qw/banana apple orange apple orange apple pear/;
my %counts;
++$counts{$_} for @array;

这会导致像这样的哈希

my %counts = ( apple => 3, banana => 1, orange => 2, pear => 1 )

如果for您愿意,可以使用块和显式循环计数器变量编写循环,如下所示

for my $word (@array) {
  ++$counts{$word};
}

具有完全相同的效果。

于 2013-08-23T00:20:53.880 回答
1

您可以使用exists.

http://perldoc.perl.org/functions/exists.html

给定一个指定散列元素的表达式,如果散列中的指定元素曾经被初始化,则返回 true,即使相应的值未定义。

foreach my $fruit (@array) {
    if (exists $hash{$fruit}) {
        $hash{$fruit}++;
    }
}
于 2013-08-23T00:20:40.030 回答
1

假设您有一个名为@array. 您可以使用 访问数组的第 0 个元素$array[0]

哈希是相似的。%hash的香蕉元素可以通过$hash{'banana'}.

这是一个非常简单的例子。它利用了隐式变量$_和一些字符串插值:

use strict;

my @array = qw/banana apple orange apple orange apple pear/;

my %hash;
$hash{$_} += 1 for @array;              #add one for each fruit in the list
print "$_: $hash{$_}\n" for keys %hash; #print our results

如果需要,您可以检查是否存在特定的哈希键:if (exists $hash{'banana'}) {...}.

你最终会看到一个叫做“hashref”的东西,它不是一个散列而是对一个散列的引用。在这种情况下,$hashref$hashref->{'banana'}

于 2013-08-23T00:25:17.030 回答
1

我想在这里理解你:

  1. 你有一个数组和一个哈希。
  2. 您想计算数组中的项目并查看它们出现的次数
  3. 但是,只有当这个项目在你的哈希中。

将哈希视为键控数组。数组有一个位置。您可以谈论第 0 个元素或第 5 个元素。只有第 0 个元素,它们只有第 5 个元素。

让我们看一个哈希:

my %jobs;
$jobs{bob} = "banker";
$jobs{sue} = "banker";
$jobs{joe} = "plumber;

就像我们可以谈论数组中第 0 位的元素一样,我们可以谈论带有 of 的元素bob。就像第 0 位只有一个元素一样,也只能有一个键为 的元素bob

哈希提供了一种快速查找信息的方法。例如,我可以快速找出 Sue 的工作:

print "Sue is a $jobs{sue}\n";

我们有:

  • 一个充满项目的数组。
  • 包含我们要计算的项目的哈希
  • 另一个带有总数的哈希。

这是代码:

use strict;
use warnings;
use feature qw(say);

my @items       = qw(.....);   # Items we want to count
my %valid_items =   (....);    # The valid items we want

# Initializing the totals. Explained below...
my %totals;
map { $totals{$_} = 0; } keys %valid_items;

for my $item ( @items ) {
    if ( exists $valid_items{$item} ) {
        $totals{$item} += 1;  #Add one to the total number of items
    }
}

#
# Now print the totals
#
for my $item ( sort keys %totals ) {
    printf "%-10.10s  %4d\n", $item, $totals{$item};
}

map命令获取右侧的项目列表(在我们的例子中)keys %valid_items并遍历整个列表。

因此:

map { $totals{$_} = 0; } keys %valid_items;

是一种简短的说法:

for ( 键 %valid_items ) { $totals{$_} = 0; }

我使用的其他东西是,它以数组(好的列表)的形式返回我的哈希的所有键。因此,我回来了apple,,当我说。bananaorangeskeys %valid_items

exists`[exists](http://perldoc.perl.org/functions/exists.html) is a test to see if a particular key is in my hash. The value of that key might be zero, a null string, or even an undefined value, but if the key is in my hash, the函数将返回一个真值。

但是,如果我们可以使用exists来查看密钥是否在我的%valid_items哈希中,我们可以使用%totals. 它们具有相同的密钥集。

相反,或者创建一个%valid_items哈希,我将使用一个@valid_items数组,因为数组比哈希更容易初始化。我只需要列出这些值。我可以使用以下命令,而不是使用keys %valid_items获取键列表@valid_items

use strict;
use warnings;
use feature qw(say);

my @items = qw(banana apple orange apple orange apple pear);   # Items we want to count
my @valid_items = qw(banana apple orange);    # The valid items we want

my %totals;
map { $totals{$_} = 0; } @valid_items;

# Now %totals is storing our totals and is the list of valid items

for my $item ( @items ) {
    if ( exists $totals{$item} ) {
        $totals{$item} += 1;  #Add one to the total number of items
    }
}

#
# Now print the totals
#
for my $item ( sort keys %totals ) {
    printf "%-10.10s  %4d\n", $item, $totals{$item};
}

这打印出来:

apple          3
banana         1
orange         2

我喜欢使用printf来保持表格整洁有序。

于 2013-08-23T01:57:27.827 回答
1

这将更容易理解,因为我也是在 2 个月前开始编写代码的。

use Data::Dumper;
use strict;
use warnings;
my @array = qw/banana apple orange apple orange apple pear/;

my %hashvar;
foreach my $element (@array) {
    #Check whether the element is already added into hash ; if yes increment; else add. 
    if (defined $hashvar{$element}) {  
        $hashvar{$element}++;
    }
    else {
        $hashvar{$element} = 1;

    }

}
print Dumper(\%hashvar);

将输出输出为 $VAR1 = { 'banana' => 1, 'apple' => 3, 'orange' => 2, 'pear' => 1 }; 干杯

于 2013-08-23T02:42:51.113 回答