Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Perl在单个元素的数组散列中循环_Arrays_Perl_Loops_Hash - Fatal编程技术网

Arrays Perl在单个元素的数组散列中循环

Arrays Perl在单个元素的数组散列中循环,arrays,perl,loops,hash,Arrays,Perl,Loops,Hash,我有一个数组散列,如图所示: my %hash = ( 234 => ["aa", "bb", "aa", "ab", "aa"], 235 => ["aa", "ab", "aa", "bb", "aa"], 236 => ["bb", "aa", "aa", "aa", "bb"], ... ) 我试图遍历每个值的第一个元素,并计算bb的出现次数 例如,在上面的散列中,对于显示的所有第一个元素,我有一个匹配项bb。我需要将这个数字(所有数组的第0个元素中“

我有一个数组散列,如图所示:

my %hash = (
  234 => ["aa", "bb", "aa", "ab", "aa"],
  235 => ["aa", "ab", "aa", "bb", "aa"],
  236 => ["bb", "aa", "aa", "aa", "bb"],
  ...
)
我试图遍历每个值的第一个元素,并计算
bb
的出现次数

例如,在上面的散列中,对于显示的所有第一个元素,我有一个匹配项
bb
。我需要将这个数字(所有数组的第0个元素中“bb”的数量)放入一个新数组,然后移动到下一组元素

对于上面的示例,我将循环遍历数组的所有4个元素,并获得一个带有
(1,1,0,1,1)
的最终数组


我在获得正确的代码方面遇到了很多困难,还没有找到类似的问题。任何帮助都将不胜感激

一个简单的解决方案:迭代散列值。对于每个值,迭代数组的成员,并在需要时将1添加到结果数组中:

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

my %hash = (234 => [qw/aa bb aa ab aa/],
            235 => [qw/aa ab aa bb aa/],
            236 => [qw/bb aa aa aa bb/],
           );

my @result;

for my $value (values %hash) {
    my $i = 0;
    for (@$value) {
        $result[$i++] += 'bb' eq $_;
    }
}

print "@result\n";
这是一种更像perl的方式(不一定更好)。除非那些维护代码的人很熟悉perl,否则它就不那么清晰了。尽管如此,了解map和grep并不是一个坏主意。一旦您熟悉了它们,它们可以帮助您更清楚地理解代码的意图。我建议仔细检查每个解决方案,并尝试找出每个解决方案的工作原理

此解决方案将处理太短的阵列,但根据应用程序的不同,这可能是您想要的,也可能不是

use warnings;
use strict;

use Data::Dumper;

my %hash = (
    '234' => [qw(aa bb aa ab aa)],
    '235' => [qw(aa ab aa bb aa)],
    '236' => [qw(bb aa aa aa bb)],
);

my @result = ();

while ( grep {scalar @{$_}} values %hash ) {
    push @result, scalar @{[
        grep {$_ eq 'bb'}
            map {shift @{$_}}
                values %hash
    ]};
}

print Dumper \@result;
是对符合特定条件的列表中的值进行计数的最佳工具。只需迭代哈希值列表中的每个条目,即可获得每个元素的计数

此代码假定每个哈希值数组具有相同的长度,并使用第一个元素的长度作为所有元素的大小

use strict;
use warnings;

my %data = (
  234 => [ qw/aa bb aa ab aa/ ],
  235 => [ qw/aa ab aa bb aa/ ],
  236 => [ qw/bb aa aa aa bb/ ],
);

my @count_bb;
for my $i ( 0 .. $#{(values %data)[0]} ) {
  $count_bb[$i] = grep { $_->[$i] eq 'bb' } values %data;
} 

print "@count_bb\n";
输出

1 1 0 1 1
ab => (0, 1, 0, 1, 0)
bb => (1, 1, 0, 1, 1)
aa => (2, 1, 3, 1, 2)
此备选方案将创建一个哈希,其中包含哈希值数组中每个不同值的计数。第一步初始化散列,使每个元素中有正确数量的零,第二步根据数据中遇到的每个值增加计数,最后一个循环打印得到的
%counts
散列的内容

use strict;
use warnings;

my %data = (
  234 => [ qw/aa bb aa ab aa/ ],
  235 => [ qw/aa ab aa bb aa/ ],
  236 => [ qw/bb aa aa aa bb/ ],
);

my %counts;
$counts{$_} = [ (0) x @{(values %data)[0]} ] for map @$_, values %data;

for my $i ( 0 .. $#{(values %data)[0]} ) {
  $counts{$_}[$i]++ for map $_->[$i], values %data;
} 

while (my ($k, $v) = each %counts) {
    printf "%s => (%s)\n", $k, join ', ', @$v;
}
输出

1 1 0 1 1
ab => (0, 1, 0, 1, 0)
bb => (1, 1, 0, 1, 1)
aa => (2, 1, 3, 1, 2)

如果您使用实际的perl语法展示了数据结构的样子,那么您的问题就更容易理解了!哦,这就是它的意思。回答得好;我想知道你为什么不循环使用
值%hash
,因为除了获取值之外,你没有使用
$key
做任何事情。@choroba:我刚刚学到了一些关于Perl的知识。我本不希望
$result[$I++]+='bb'eq$\uuz>没有运行时错误,但在
perlop
中发现了这一点。关系运算符。。。返回1表示true,并返回定义的空字符串“”的特殊版本,该字符串将计为零,但不受有关不正确数字转换的警告的影响谢谢,第一种方法对我很有效。我真的很感谢你的帮助。