当perl中的键相同时,连接哈希值

时间:2012-06-05 15:13:13

标签: perl hash

我有一个哈希 类似的东西:

abc=>1
hello=>32
abc=>4
hello=>23
hello=>12
xyz=>18

我们如何连接其键相同的值。 所以输出将是:

abc=>"1,4"
hello=>"23,12,32"
xyz=>"18".

我尝试通过键对哈希进行排序然后检查每个键,如果它们相同则连接值,但我不知道如何比较同一个循环中的两个键。

提前谢谢。

4 个答案:

答案 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块相同,它在输入结束时执行以下代码。