5

Currently when I want to build a look-up table I use:

my $has_field = {};
map { $has_field->{$_} = 1 } @fields;

Is there a way I can do inline initialization in a single step? (i.e. populate it at the same time I'm declaring it?)

Brad Mace
  • 27,194
  • 17
  • 102
  • 148

3 Answers3

14

Just use your map to create a list then drop into a hash reference like:

my $has_field = { map { $_ => 1 } @fields };
Lee
  • 311
  • 2
  • 4
3

Update: sorry, this doesn't do what you want exactly, as you still have to declare $has_field first.

You could use a hash slice:

@{$has_field}{@fields} = (1)x@fields;

The right hand side is using the x operator to repeat one by the scalar value of @fields (i.e. the number of elements in your array). Another option in the same vein:

@{$has_field}{@fields} = map {1} @fields;
dan1111
  • 6,576
  • 2
  • 18
  • 29
  • This works correctly but still requires declaring `$has_field` separately when using `use strict;`. It's still a good trick to know though. – Brad Mace Aug 17 '12 at 15:07
2

Where I've tested it smart match can be 2 to 5 times as fast as creating a lookup hash and testing for the value once. So unless you're going to reuse the hash a good number of times, it's best to do a smart match:

if ( $cand_field ~~ \@fields ) { 
   do_with_field( $cand_field );
}

It's a good thing to remember that since 5.10, Perl now has a way native to ask "is this untested value any of these known values", it's smart match.

Axeman
  • 29,660
  • 2
  • 47
  • 102