Perl Hash麻烦

时间:2013-08-23 00:09:24

标签: arrays perl hash

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程序员,提前谢谢!

5 个答案:

答案 0 :(得分: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};
}

具有完全相同的效果。

答案 1 :(得分:1)

您可以使用exists

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

  

给定一个指定哈希元素的表达式,返回true   如果哈希中的指定元素已经初始化,甚至   如果相应的值未定义。

foreach my $fruit (@array) {
    if (exists $hash{$fruit}) {
        $hash{$fruit}++;
    }
}

答案 2 :(得分:1)

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

哈希是相似的。可以使用%hash访问$hash{'banana'}的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'}

答案 3 :(得分:1)

我想在这里了解你:

  1. 你有一个数组和一个哈希。
  2. 您想要计算数组中的项目并查看它们出现的次数
  3. 但是,只有当这个项目在您的哈希中时。
  4. 将哈希视为键控数组。阵列有一个位置。你可以谈论第0个元素或第5个元素。只有一个第0个元素,它们只有一个第5个元素。

    让我们看一下哈希:

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

    就像我们可以在第0个位置讨论数组中的元素一样,我们可以用bob来讨论元素。就像第0个位置只有一个元素一样,只有一个元素的键为bob

    哈希提供了查找信息的快捷方式。例如,我可以很快找到苏的工作:

    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(keys%valid_items){        $ totals {$ _} = 0;     }

    我使用的其他东西是keys,它以数组(okay list)的形式返回哈希的所有键。因此,当我说apple时,我会回来bananaorangeskeys %valid_items

    [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`函数将返回一个真值。

    但是,如果我们可以使用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来保持表的良好和有序。

答案 4 :(得分: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         }; 干杯