Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Hi,
I have to define a hash whose key is defined by various values, so can i concatinate the values to get a unique key?
Is this the right way or some other option available in perl?
my $key = join ("",$value1,$value2,$value3,$value4,$value5);
my @value= @{$Config{$key}};
cheers
Re: can i concatenate various value to form a unique key
by missingthepoint (Friar) on Jul 03, 2009 at 06:41 UTC
|
so can i concatinate the values to get a unique key?
Maybe. Consider this:
$value1 = "a";
$value2 = "b";
$value3 = "c";
$value4 = "de";
$value5 = "f";
my $key = join("", $value1,$value2,$value3,$value4,$value5);
print $key;
$value3 = "cd";
$value4 = "e";
$key = join("", $value1,$value2,$value3,$value4,$value5);
print $key;
So if you need different keys in situations like above, no. Perhaps you could generate a string that encodes the structure of the separate values, e.g.:
my $str = "v1=$value1,v2=$value2,v3=$value3,v4=$value4,v5=$value5";
# use $str for key, or perhaps generate hash of $str and use that
Ca3n w2e ple6ase st4op doi5ng th4is?
| [reply] [d/l] [select] |
Re: can i concatenate various value to form a unique key
by ambrus (Abbot) on Jul 03, 2009 at 08:07 UTC
|
Sure, just use pack "(J/A)*", @strings instead of join "", @strings to concatenate the strings to a unique key. (On older perls, use I instead of J.)
| [reply] [d/l] [select] |
Re: can i concatenate various value to form a unique key
by Marshall (Canon) on Jul 03, 2009 at 09:26 UTC
|
It is completely fine to make a hash key from other strings. like:
#!/usr/bin/perl -w
use strict;
my %hash;
$hash{'my_mother=Nice,my_brother=Great;3;45;987;'}='True';
foreach my $key (keys %hash)
{
print "$key VALUE =$hash{$key}\n";
}
__END__
prints:
my_mother=Nice,my_brother=Great;3;45;987; VALUE =True
Update:
I would argue that this is not the best way:
my $key = join ("",$value1,$value2,$value3,$value4,$value5);
consider:
my $key ="$value1$value2$value3$value4$value5";
if say $value3 doesn't exist, then,
$key = "$value1$value2$value4$value5";
Oooops!...maybe a problem!!!
$hash{"$value1;$value2;$value3;$value4;$value5"} = 123;
is "better" (provided that ";" doesn't occur in the $values).
The reason for the ";" is so that there will always be a unique value even
if one of the $value vars is ""!.
| [reply] [d/l] |
|
hoo
so is it possible to have mutiple values as key whose combination will be unique?
and I dont have to download any CPAN modules for the same also?
| [reply] |
|
The short answer is yes. A hash key can be any string as long as that string is unique. The "classic example" is printing a file and omitting duplicate lines that have been seen before....
#!usr/bin/perl -w
use strict;
my %seen;
while (<DATA>)
{
print unless $seen{$_}++;
}
#Prints:
#1 2 this is a line with 1 and 2
#3 a line with just 3
#5,6 five before 6
#5,6 five before six (different)
#6,5
#blah
__DATA__
1 2 this is a line with 1 and 2
3 a line with just 3
1 2 this is a line with 1 and 2
3 a line with just 3
5,6 five before 6
5,6 five before six (different)
6,5
blah
blah
In general, I would not concatenate keys together. Well, until you have learned multi-dimensional structs, I would say that concatenating 2 things and not more is "ok". There are some advanced techniques where say 8 dimensions can be combined into a single hash key, but those situations are seldom and not applicable for normal code (a way to describe state tables and a way to simplify horrifically complex logic statements).
| [reply] [d/l] |
Re: can i concatenate various value to form a unique key
by JavaFan (Canon) on Jul 03, 2009 at 10:17 UTC
|
As explained else where in the thread, that has the potential to not be unique.
It's a little known feature that Perl actually supports autoconcatenation of strings used as hash keys, joining them together using $;, which by default contains "\034" which is rare enough that it's unlikely unwanted duplicates are formed. So, you can write:
my @value = @{$Config{$value1,$value2,$value3,$value4,$value5}};
without having to join them yourself.
This was how people did multilevel hashes using perl4.
For more details, see the perlvar entry about $;. | [reply] [d/l] [select] |
|
i am initialize these variable with some default value and then will the same problem exists?
and for the default key combination also hash have some value like
my $value1 = 'x';
my $value2 = 'x';
my $value3 = 'x';
my $value4 = 'x';
----
#code where actual value will be assigened to the variables and only $
+value2 didnt get assigned to any value so $value2='x' itself
----
my @value = @{$Config {'hai','x','there','bye'}};
if my has have a value for thsi key also will it be an issue?
| [reply] [d/l] |
Re: can i concatenate various value to form a unique key
by citromatik (Curate) on Jul 03, 2009 at 07:50 UTC
|
I don't know exactly what you are trying to address (sounds like an XY Problem to me). You can use any string as a key in a hash, as long as it is unique in the hash, but building a hash whose keys are the concatenated values of other keys sounds like a design problem to me, maybe other data structures should be used instead
Could you please give a step backwards and elaborate a bit more the kind of problem you are trying to solve and why do you think that such a hash is a good option?
| [reply] |
|
Hi,
I am planning to have a hash like
%hash = {g1 => [start_date1,end_date2]
g2 => [start_date1,end_date2]
};
but i dont have a unique value of g1 and g2..
i will get unique value with combination of some values like value1 value2 value3 ..value5
so i planned to derive g with concatenation of these values
assuming that a hash cannot have mutiple values of as a key.
I thik the background is explained better now. | [reply] [d/l] |
|
each hash like:
start => "some start date",
end => "some end date",
parm1 => "some data1",
parm2 => "some data2",
parm3 => "some data3",
| [reply] [d/l] |
|
Maybe I am wrong, but contrary to the others who have replied already, I think you are misinterpreting your problem (sorry if I misinterpreted you! :).
Do you want the following:
%hash = (
g1 => [value1, value2, value3],
g2 => [value4, value5, value6...]
);
i.e. do you want each key to have multiple values associated? If this is the case you need a reference to an array containing all the values (see perlref). You already have that situation in the example you give: g1 => [$start_date1,$end_date1], so, to concatenate more values, you will need a reference to an AoA (array of arrays). Again, sorry if I totally misinterpreted your problem, but if you think I am close, let me know and we will elaborate it a little more
| [reply] [d/l] [select] |
|
|
Re: can i concatenate various value to form a unique key
by SuicideJunkie (Vicar) on Jul 03, 2009 at 14:01 UTC
|
Ensuring uniqueness is quite easy, but you definitely don't want to concatenate. It sounds like you want a HoHoHoHoHoA.
See: perlref and use Data::Dumper to make it easy to see the deep structure of your variable via print Dumper \%hash.
For a config type example: my %config;
my $inDir = $config{directories}{input};
my $tempDir = $config{directories}{temp};
my $outDir = $config{directories}{output};
my $bgColor = $config{colors}{background};
...
| [reply] [d/l] [select] |
|
|