On Nov 24, Alexandre Checinski said:

I have lists that looks like this :
(A,B,C,1,5)
(A,B,C,1,2)
(A,B,2,1,2)
(A,B,C,D,1)
(A,B,Y)

And I would like to get something like this :

Here's how to do it without using eval().

  use strict;
  use warnings;
  use Data::Dumper;
  $Data::Dumper::Indent = 1;

  my @lists = (
    [qw( A B C 1 5 )],
    [qw( A B C 1 2 )],
    [qw( A B 2 1 2 )],
    [qw( A B C D 1 )],
    [qw( A B Y )],
  );

  my %hash;

  for my $path (@lists) {
    add_path([EMAIL PROTECTED], \%hash);
  }

  print Dumper(\%hash);

  sub add_path {
    my $path = shift;

    if (@$path) { add_path($path, $_[0]{shift @$path}) }
    else { $_[0] = 1 }
  }

It works because of a nifty Perl behavior: the elements of @_ (the arguments to a function) are *aliases* to the things passed to the function. That means, by altering $_[0], you can alter the first argument to a function.

In my code, I've shift()ed the @_ array, so altering $_[0] is actually changing the *second* argument to the function. But anyway.

We send the add_path() function an array reference (the path) and a reference to where to store the path. So for (A, B, C, 1, 5), we do:

  add_path([A,B,C,1,5], \%hash);

The add_path() function checks to see if there are still elements in the path arrayref. If there are, it removes the first part and uses it as a key to the hash reference it was given and calls itself again:

  add_path([B,C,1,5], $_[0]{A});

where $_[0] is \%hash, which calls

  add_path([C,1,5], $_[0]{B});

where $_[0] is $hash{A}, which calls

  add_path([1,5], $_[0]{C});

where $_[0] is now $hash{A}{B}, which calls

  add_path([5], $_[0]{1});

where $_[0] is now $hash{A}{B}{C}, which calls

  add_path([], $_[0]{5});

where $_[0] is now $hash{A}{B}{C}{1}...

Now, when the path is empty, instead of calling add_path() again, we set $_[0] to 1.

This means that $hash{A}{B}{C}{1}{5} is set to 1.

This can be done WITHOUT a recursive function.  Exercise to the reader.

--
Jeff "japhy" Pinyan        %  How can we ever be the sold short or
RPI Acacia Brother #734    %  the cheated, we who for every service
http://www.perlmonks.org/  %  have long ago been overpaid?
http://princeton.pm.org/   %    -- Meister Eckhart

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to