More Hash problems

Tkil tkil at scrye.com
Wed Jun 5 18:51:14 CDT 2002


>>>>> "Jason" == Jason White <jasona at inetarena.com> writes:

Jason> I start with a numerically keyed list of arrays.  The first
Jason> element of each array is a name.

By "keyed list", do you mean hashes with numeric keys and references
to arrays for values?  That is:

| my %num_keyed = (  3 => [ 'three',     1, 2, 3, 4 ],
|                   11 => [ 'eleven',    4, 3, 9, 1, 'foo', 'bar' ],
|                   17 => [ 'seventeen', 2, 4, 'gizzard' ] );

Jason> The goal is to have one hash of rules indexable by integer keys
Jason> and another indexable by name.

Do you want the values of these two hashes to refer to the same
instances of the rules (Tom's "shallow copy", or aliasing), or do you
want two totally different and independent ["deep"] copies?

Anyway, shallow copy of values:

| my %name_keyed_shallow = map { $_->[0] => $_ }      values %num_keyed;

Or:

| my %name_keyed_shallow;
| foreach my $rule ( values %num_keyed )
| {
|     my $name = $rule->[0];
|     $name_keyed_shallow{$name} = $rule;
| }

Note how the variable names make this snippit almost self-documenting.

I personally prefer the "map" version; it's more compact, probably
faster, and it more clearly communicates my intent: taking a list as
input, getting a transformed list as output.

Deep copy is similar, except I create a new copy of the rule array by
dereferencing it and then putting it inside an anonymous array ref:

| my %name_keyed_deep    = map { $_->[0] => [ @$_ ] } values %num_keyed;

To see the difference, have fun with this:

| use Data::Dumper qw();
| print Data::Dumper->Dump(
|    [    \%num_keyed, \%name_keyed_shallow, \%name_keyed_deep ],
|    [ qw(  num_keyed    name_keyed_shallow,   name_keyed_deep ) ] );

>>>>> "Tom" == Tom Phoenix <rb-pdx-pm at redcat.com> writes:

Tom> "Indexable by integer keys" sounds like "a job for an array",
Tom> doesn't it?

Tom, I agreed with most of what you said, but this particular issue
depends on how big / sparse the integer keys are.  If my integer keys
are (1, 10, 100, 1000, 10000), then a hash is the better choice.

t.
TIMTOWTDI



More information about the Pdx-pm-list mailing list