tags:

views:

165

answers:

3

EDIT Sorry I forgot the most important part here. Each key can have more than one value. Apologies to those who already answered. print and join will be used later to print multiple values for $key on a single line.

In the example code below, assuming that the value $keyvalue is constantly changing, I am attempting to use a single line (or something similarly contained) to test and see if the current $keyvalue already exists. If it does, then do nothing. If it does not, then push it. This line would reside within a while statement which is why it needs to be contained within a few lines.

Preserving order does not matter as long as there are no duplicate values.

my $key = "numbers";
my $keyvalue = 1;

my %hash = ($key => '1');

push (@{$hash{$key}}, $keyvalue) unless exists $hash{$key};

I am not getting any errors with use strict; use warnings;, but at the same time this is not working. In the example above, I would expect that since the default value is 1 that the $keyvalue would not be pushed as it is also 1. Perhaps I have gotten myself all turned around...

Are there adjustments to get this to work or any alternatives that can be used instead to accomplish the same thing?

+3  A: 

You can just do:

$hash{$key} = $keyvalue unless exists $hash{$key};

This will add the key,value pair ($key,$keyvalue) only if the key is not already present in the hash.

codaddict
A: 

You don't push values into a hash, since a hash needs key/value pairs and push only adds a value. In your expression you're treating $hash{$key} as an array reference to which you want to add a value. You just have to normally assign the value to the hash.

kemp
+5  A: 

Easiest way would be to put an anonymous hash at $hash{$key}. You only care about the keys of that anonymous hash.

#!/usr/bin/perl

use strict; use warnings;

my %hash;

while ( my $line = <DATA> ) {
    chomp $line;
    my ($key, $val) = split /\s*=\s*/, $line;
    $hash{$key}{$val} = undef;
}

for my $key ( keys %hash ) {
    printf "%s : [ %s ]\n", $key, join(' ', keys %{ $hash{$key} });
}

__DATA__
key = 1
key = 2
other = 1
other = 2
key = 2
key = 3

In the output, key = 2 appears only once:

C:\Temp> h
other : [ 1 2 ]
key : [ 1 3 2 ]
Sinan Ünür