fugu
fugu

Reputation: 6578

Modify key if it already exists

I'm writing a piece of code that creates a HoAs and loops through for each key. The snippet below shows a basic example of the problem I'm having.

#!/usr/bin/perl 
use strict;
use warnings;

my @array1 = qw (1 1 3 4 5); # Note that '1' appears twice
my @array2 = qw (a b c d e);
my @array3 = qw (6 7 8 9 10);
my @array4 = qw (f g h i j);

my %hash;   
push @{$hash{$array1[$_]}}, [ $array2[$_], $array3[$_], $array4[$_] ] for 0 .. $#array1;

for my $key (sort keys %hash) {
    my ($array2, $array3, $array4) = @{$hash{$key}[-1]};
    print "[$key] $array2\t$array3\t$array4\n"; 
}

Output:

[1] b   7   g
[3] c   8   h
[4] d   9   i
[5] e   10  j

For the data I'm actually using (as opposed to this example) I have been using a key that I've just realised isn't unique, so, as above I end up overriding non-uniqe keys. I'm mainly using these values as keys in order to sort by them later.

My question is either:

A) I can perform the above task for each key unless (exists $hash{$array1}) in which case I can modify it

or

B) Is there a way to sort by those values, in which case I could use another, non-redundant key.

Thanks!

Upvotes: 0

Views: 75

Answers (1)

amon
amon

Reputation: 57640

so, as above I end up overriding non-uniqe keys

You aren't. Let's print out the whole contents of that hash:

for my $key (sort { $a <=> $b } keys %hash) {  # sort numerically!
  for my $array (@{ $hash{$key} }) {           # loop over all instead of $hash{$key}[-1] only
    say "[$key] " . join "\t", @$array;
  }
}

Output:

[1] a   6       f
[1] b   7       g
[3] c   8       h
[4] d   9       i
[5] e   10      j

You would be overriding the values if you were building the hash like

$hash{$array1[$_]} = [ $array2[$_], $array3[$_], $array4[$_] ] for 0 .. $#array1;

(And printing it as)

for my $key ( ... ) {
  say "[$key] " . join "\t", @{ $hash{$key} };
}

That is, assigning instead of pushing.

If you want to keep the first value assigned to each key, use the //= operator (assign if undef).

Upvotes: 2

Related Questions