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?
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.