PoorLuzer has asked for the wisdom of the Perl Monks concerning the following question:

How to turn :
for (my $dx = 0; $dx < @ListOfRecords; $dx += 2) { $MappingOfRecords { $ListOfRecords[1 + $dx] } = $ListOfRec +ords[$dx]; }

into something shorter/functional?

I tried a lot using map constructs but failed :-(

Replies are listed 'Best First'.
Re: Transforming a for loop to a more functional approach?
by GrandFather (Saint) on Mar 03, 2009 at 02:07 UTC
    use Data::Dump::Streamer; my @ListOfRecords = qw(1 a 2 b 3 c 4 d); my %MappingOfRecords = reverse @ListOfRecords; Dump \%MappingOfRecords;

    Prints:

    $HASH1 = { a => 1, b => 2, c => 3, d => 4 };

    True laziness is hard work
      But ofcourse! The first element is the key and the next is its value! What's wrong with me :-(
      Nice answer both of you!

      An unrelated question, why not just :
      use Data::Dumper;

        Habit mostly. I like Streamer's default output better and I don't have to remember to print the result:

        use Data::Dumper; use Data::Dump::Streamer; my @ListOfRecords = qw(1 a 2 b 3 c 4 d); my %MappingOfRecords = reverse @ListOfRecords; print Dumper \%MappingOfRecords; Dump \%MappingOfRecords;

        Prints:

        $VAR1 = { 'c' => '3', 'a' => '1', 'b' => '2', 'd' => '4' }; $HASH1 = { a => 1, b => 2, c => 3, d => 4 };

        True laziness is hard work
Re: Transforming a for loop to a more functional approach?
by hbm (Hermit) on Mar 03, 2009 at 02:05 UTC

    I think you are trying to create a hash where the second array element becomes a key and the first element becomes its value; and so on for fourth and third elements, etc. In that case, try this:

    my @list = qw(a b c d e f g h); my %hash = reverse @list; print map { "$_ -> $hash{$_}\n" } keys %list; #Prints: h -> g b -> a d -> c f -> e

    But note that both methods complain if your array length is odd.

      ++, I gave my answer right before bed, and then laying there in the dark I thought, "Oh, duh, reverse it into a hash!" :)... Much better.
Re: Transforming a for loop to a more functional approach?
by bellaire (Hermit) on Mar 03, 2009 at 02:01 UTC
    It's not particularly pretty, but the following using map should work:
    %MappingOfRecords = map { $_%2 ? () : ($ListOfRecords[$_+1] => $ListOfRecords[$_]) } (0..$#ListOfRecords);
Re: Transforming a for loop to a more functional approach?
by educated_foo (Vicar) on Mar 03, 2009 at 03:52 UTC
    Why? It's already short and easy to understand.
      No.
      hbm and GrandFather's answer is the short and easy way to do it... and the more readable way.
      PERL is not C. Mistaking it to be so really messes up things and makes you suffer bad performance, debugging and processing time.
        hbm and GrandFather's answer is the short and easy way to do it... and the more readable way.
        Yes, but both do something different than the code of the OP did. hbm and GrandFather both create a new hash - while the OP extends an existing hash. Now, if the hash was initially empty, this is the same thing. But we cannot decude that from the OP's snippet, so it would be quite bold to state what they did is the way of doing it. In fact, it's quite unPerlish to claim there exists the way of doing something.