Take the 2-minute tour ×

I have a file which consists of following:

A  1
A  2
B  3
B  4
B  5
B  6
C  7
A  8  

I want to get all unique keys in first column, but get all corresponding values for that unique key, i.e I need to get:

A 1,2,8
B 3,4,5,6
C 7

What would be the best way to do this?
(I've heard that Perl has good support to solve this, but I'm new to Perl.)

share|improve this question
add comment

3 Answers

try this:

open my $fh, '<', "data_filename";
my %map;

while(my $line = <$fh>) {
  my ($key, $val) = split(/\s+/, $line);
  push @{$map{$key}}, $val;
share|improve this answer
Thanks Brad for your time in answering. –  Ravishankar Mar 2 '11 at 6:05
add comment

You probably want a hash, where each value in the hash is an array reference.

my %values;
while (<>) {
    my ($left, $right) = split(/ /,$_,2);
    my $array = $values{$left};
    if (!$array) {
        $array = [];
        $values{$left} = $array;

You can verify that this has produced the correct data structure with Data::Dumper:

use Data::Dumper;
print Dumper(\%values);
share|improve this answer
You can't create a list reference, you can however create an array reference. And no, they aren't quite the same thing. –  Brad Gilbert Mar 1 '11 at 18:11
Fair enough (fixed) –  Adam Batkin Mar 1 '11 at 18:14
I think you mean if (!$array)... but in general, this type of coding is not necessary due to Perl's autovivification of container types. You could replace every line of the while loop below the split with push @{$values{$left}}, $right as erickb's example shows. –  Eric Strom Mar 1 '11 at 20:13
Thanks Adam for your time in answering this. –  Ravishankar Mar 2 '11 at 6:05
add comment

This is just another possible solution for the sake of completeness. In this case, the hash stores a the key and a string containing your values.

use warnings;
use strict;

my %hash = ();
open (FILE, "input.txt") or die "";
(my $key, my $value) = split;
    $value = ",".$value if exists $hash{$key};
    $hash{$key}.= $value;

foreach my $key (sort keys %hash){
    print "$key $hash{$key}\n";

As always, there's more than one way to do it.

share|improve this answer
Thanks a lot Cooper. –  Ravishankar Mar 2 '11 at 5:58
This also wouldn't put the numbers in order though, so obviously if order is important use the anonymous array within a hash implementation. –  Cooper Mar 2 '11 at 6:17
add comment

Your Answer


