Reputation: 47
I have a hash
something like :
abc=>1
hello=>32
abc=>4
hello=>23
hello=>12
xyz=>18
how can we concatenate the values, whose keys are same.
So the output will be:
abc=>"1,4"
hello=>"23,12,32"
xyz=>"18".
I tried by sorting the hash by keys then checking for each key, if they are same then concatenate the value, but i am not getting that how to compare two keys in same loop.
Thanks in advance.
Upvotes: 2
Views: 5782
Reputation: 67920
Since it is unclear what you are really trying to do, I am guessing that you have a file that you need to change. In which case, a one-liner might be in order.
perl -lwne '
($k,$v) = split /=>/;
$data{$k} = join ",", $data{$k} // (), $v }{
print "$_=>$data{$_}" for keys %data' input.txt > output.txt
Output:
hello=>32,23,12
abc=>1,4
xyz=>18
Note that the keys in the output will not be in the same order as the input. You can sort the keys if you like, but I opted not to.
Explanation:
-l
will remove line endings while reading, and put them back while printing-n
will place a while(<>)
loop around the program, reading the file (or STDIN) line by line.//
is the defined-or
operator. It will return the RHS if the LHS is undefined.}{
is the eskimo kiss operator which only works with the -n
option. What it does is basically the same as an END block, it performs the following code at the end of the input.Upvotes: 0
Reputation: 22471
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";
}
Upvotes: 1
Reputation: 126762
The exact way this works depends on the real source of your data, but this program shows a way to read the information from the DATA
filehandle to build and dump a hash.
The values of the hash are anonymous arrays that contain all the values corresponding to the same key.
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
output
abc => 1,4
hello => 32,23,12
xyz => 18
Upvotes: 7
Reputation: 33928
If it's a list with key value pairs you are talking about then you could do something like:
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;
}
Upvotes: 3