in reply to Re: splitting directly to hash
in thread splitting directly to hash

Hi Dave
Could you please explian the map function based solution. It works but I do not understand why :-)
Thanks

Replies are listed 'Best First'.
Re^3: splitting directly to hash
by ikegami (Patriarch) on Nov 21, 2006 at 16:44 UTC
    1. split breaks down the string into a list of values (('1', '2', '3', '4', '5')).
    2. For every element in the list,
      1. map transforms the element into a list consisting of the element and undef. (('1', undef)).
    3. map returns a list consisting of the aggregation of all the smaller lists (('1', undef, '2', undef, '3', undef, '4', undef, '5', undef)).
    4. The list returned by map is assigned to the hash.

    By the way, here's a shorter solution:

    my $keys = '1 2 3 4 5 6'; my %hash = $keys =~ /(\S+)()/g;

    To use an environment variable, substitute $keys with $ENV{varname}.

Re^3: splitting directly to hash
by calin (Deacon) on Nov 21, 2006 at 16:47 UTC

    Try to visualise map as an assembly line. The right conveyor belt bring list values one by one and feeds them to the block. The block executes for each of these values and in turn produces zero, one or multiple values which are put on the left conveyor belt.

    step 0: () {map} (1 2 3) step 1: (1 undef) {map} (2 3) step 2: (1 undef 2 undef) {map} (3) step 3: (1 undef 2 undef 3 undef) {map} ()
      What a great visualization of the map function. ++! Wish I had understood it this way back when I first started.
      Seconded! Lucky for me I think it's early enough that I have a whole new conceptualization of 'map.' Thanks.

      _________________________________________________________________________________

      I like computer programming because it's like Legos for the mind.

Re^3: splitting directly to hash
by davorg (Chancellor) on Nov 21, 2006 at 16:52 UTC

    Do you know what "map" does? If not, you might take a look at the documentation.

    Let's split the code up a bit to make it easier to follow.

    my $keys = '1 2 3 4 5 6'; # this splits your input data and stores the split # up elements in an array # So @key_list ends up containing # (1, 2, 3, 4, 5, 6) my @key_list = split /\s+/, $keys; # Here's where it gets interesting. # The map block is called once for every element in # the input list and returns the list that is created # by the block. # In this case each element is converted to a two-element # list, where the first element is taken from @key_list # and the second element is the value "undef". So, for # example, the first element from @key_list returns the # two-element list (1, undef). All of this little lists # are stored together in @mapped_list. So @mapped_list # will contain: # (1, undef, 2, undef, 3, undef, 4, undef, # 5, undef, 6, undef) my @mapped_list = map { $_ => undef } @key_list; # And finally we use standard list assignment to assign # our array to a hash. The even indexed elements (indexes # 0, 2, 3, etc) become the keys and the old indexed # elements (1, 3, 5, etc) become the values. # It's just like doing: # %hash = (1 => undef, 2 => undef, 3 => undef, ...) my %hash = @mapped_list;

    Does that help at all?

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Thanks all. you guys are the best!!!
Re^3: splitting directly to hash
by holli (Abbot) on Nov 21, 2006 at 16:48 UTC
    A common misconception of map is that the left hand side of the map-block (the list that get returned by map) must have the same number of elements as the right hand side. That's not true. Every iteration can return any number of list elements to the left.

    Examples:
    print map { $_, $_, $_ } (1, 2, 3); #111222333 print map { ($_) x $_ } (1, 2, 3); #122333
    In your case all you need to do is to build an even sized list that can be assigned to a hash:
    print map { $_, ' ') } (1, 2, 3); #1 2 3
    The above is the same as
    print map { $_ => ' ' } (1, 2, 3); #1 2 3


    holli, /regexed monk/