Search code examples
arraysperliterationhashref

Perl Array index to Hash value


I'm new to Perl and I want to turn this:

$a = ["apple", "orange", "banana"];

Into this:

$b = { "apple" => 0, "orange" => 1, "banana" => 2 };

Is there an elegant way of doing this instead of iterating and assigning a counter manually?


Solution

  • This is how I usually do that:

    my $b = {};
    @$b{@$a} = 0..$#$a;
    

    Although it's not very idiomatic to use scalar references for everything; normally you would use an array variable to hold an array and a hash variable to hold a hash. That would make the array assignment look like this:

    my @a = ("apple", "orange", "banana");
    

    Or, more succinctly, like this:

    my @a = qw(apple orange banana);
    

    The hash setup then looks like this:

    my %b;
    @b{@a} = 0..$#a;
    

    This takes advantage of the ability to assign to multiple keys in a hash at once:

    my %h;
    @h{'foo','bar'} = ('zoo','wicky');
    

    That makes $h{foo} equal to 'zoo' and $h{bar} equal to 'wicky'.

    By placing the array inside the curlies on the left, you get all the elements of that array in order as the hash keys to assign. The range expression 0..$#a, where $#a is the index of the last element of the array, expands to the list of integers 0,1,2,3,4,...,$#a on the right hand side of the assignment. So each array value is mapped to its index.