我有一个哈希
类似的东西:
abc=>1
hello=>32
abc=>4
hello=>23
hello=>12
xyz=>18
我们如何连接其键相同的值。
所以输出将是:
abc=>"1,4"
hello=>"23,12,32"
xyz=>"18".
我尝试通过键对哈希进行排序然后检查每个键,如果它们相同则连接值,但我不知道如何比较同一个循环中的两个键。
提前谢谢。
答案 0 :(得分:7)
这种工作的确切方式取决于数据的真实来源,但此程序显示了一种从DATA
文件句柄中读取信息以构建和转储哈希的方法。
哈希值是匿名数组,包含与同一个键对应的所有值。
use strict;
use warnings;
my %data;
while (<DATA>) {
my ($k, $v) = /\w+/g;
push @{ $data{$k} }, $v;
}
for my $k (sort keys %data) {
printf "%s => %s\n", $k, join ',', @{ $data{$k} };
}
__DATA__
abc=>1
hello=>32
abc=>4
hello=>23
hello=>12
xyz=>18
<强>输出强>
abc => 1,4
hello => 32,23,12
xyz => 18
答案 1 :(得分:3)
如果它是一个你正在谈论的关键值对的列表,那么你可以做类似的事情:
my @kv = (
abc=>1,
hello=>32,
abc=>4,
hello=>23,
hello=>12,
xyz=>18,
);
my %hash;
while(@kv){
my $k = shift @kv;
my $v = shift @kv;
$hash{$k} = defined $hash{$k} ? "$hash{$k},$v" : $v;
}
答案 2 :(得分:1)
my @pairs = (
abc=>1,
hello=>32,
abc=>4,
hello=>23,
hello=>12,
xyz=>18,
);
my %hash;
# collect
for(my $idx = 0; $idx < scalar @pairs; $idx += 2){
my $key = $pairs[$idx];
my $val = $pairs[$idx+1];
push @{ $hash{$key} }, $val;
}
# print combined
while( my ($key, $val) = each %hash ){
print "$key = ", join(',', @$val), "\n";
}
答案 3 :(得分:0)
由于目前还不清楚你真正想做什么,我猜你有一个你需要改变的文件。在这种情况下,单行可能是有序的。
perl -lwne '
($k,$v) = split /=>/;
$data{$k} = join ",", $data{$k} // (), $v }{
print "$_=>$data{$_}" for keys %data' input.txt > output.txt
<强>输出:强>
hello=>32,23,12
abc=>1,4
xyz=>18
请注意,输出中的键与输入的顺序不同。您可以根据需要对键进行排序,但我选择不这样做。
说明:
-l
会在阅读时删除行结尾,并在打印时将其放回-n
会在程序周围放置while(<>)
循环,逐行读取文件(或STDIN)。//
是defined-or
operator。如果LHS未定义,它将返回RHS。}{
是eskimo kiss operator,仅适用于-n
选项。它的作用基本上与END块相同,它在输入结束时执行以下代码。