2012-06-05 21 views
2

相同串连的散列值我有一个哈希 是这样的:
当关键是在Perl

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

我们如何可以连接的价值观,它的键是一样的。 所以输出将是:

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

我试图通过排序的键,然后为每个键检查,如果他们是相同的,然后串联值的哈希,但我没有得到的是如何在两个键比较同样的循环。

在此先感谢。

+3

这看起来像一个键 - >值对,而不是一个散列,因为散列总是只有一个值与一个键相关联。 –

+0

你怎么能有相同的密钥哈希?你的意思是你有一个'key => value'对的数组吗? – Qtax

+4

Perl哈希不可能有两个具有相同键的元素。请描述你的潜在问题。 – Borodin

回答

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; 
} 
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 
+0

+1,不知道你可以推到未定义的参考。 – Qtax

+1

http://en.wikipedia.org/wiki/Autovivification –

+0

谢谢@Borodin,这种方法对我有用 – rahul

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"; 
} 
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(<>)循环,读取文件(或标准输入)一行一行。
  • //defined-or operator。如果LHS未定义,它将返回RHS。
  • }{eskimo kiss operator只适用于-n选项。它所做的与END块基本相同,它在输入结束时执行以下代码。
+0

嗨TLP, 我试着运行这段代码,但是这样会产生如下错误: 找到字符串,打印“$ _ => $ Rhash {$ _}”为键%Rhash'' (可能是一条从第90行开始的失控多行''字符串) (在上一行缺少分号?) 标量找到的位置预计在'print'$ _ => $ Rhash {$ _}“附近获得关键字%Rhash''。我试图纠正它,但不能,因为我不太熟悉Perl的单行程。如果你认为我犯了一些错误,或者你知道这个错误,请告诉我。在此先感谢 – rahul

+0

@rahul这是什么,我听到有关线90?你把它粘贴到其他程序文件或其他东西? – TLP