Can explain the MAP function more clearly? Thanks

Discussion in 'Perl Misc' started by yezi, Sep 28, 2005.

  1. yezi

    yezi Guest

    Hi :
    I am confused with the sentence "

    %seq_nos_set=map{$_=> 1} @seq_nos

    Thanks for any information.

    what is {$_=> 1 } mean?
    yezi, Sep 28, 2005
    #1
    1. Advertising

  2. "yezi" <> wrote in news:1127864918.739998.293400
    @f14g2000cwb.googlegroups.com:

    > Hi :
    > I am confused with the sentence "
    >
    > %seq_nos_set=map{$_=> 1} @seq_nos
    >
    > Thanks for any information.
    >
    > what is {$_=> 1 } mean?


    Have you read the documentation?

    From perldoc -f map:

    %hash = map { getkey($_) => $_ } @array;

    is just a funny way to write

    %hash = ();
    foreach $_ (@array) {
    $hash{getkey($_)} = $_;
    }

    so

    my %seq_nos_set = map{$_ => 1} @seq_nos;

    is another way of writing:

    my %seq_nos_set;
    $seq_nos_set{$_} = 1 for @seq_nos;

    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Sep 28, 2005
    #2
    1. Advertising

  3. yezi

    Paul Lalli Guest

    yezi wrote:
    > Hi :
    > I am confused with the sentence "
    >
    > %seq_nos_set=map{$_=> 1} @seq_nos
    >
    > Thanks for any information.
    >
    > what is {$_=> 1 } mean?


    { } indicates a block
    => is a fancy way of writing a comma

    So { $_ => 1 } is a block that returns a 2-element list ($_, 1)

    map() takes this block and evaluates it for each element of @seq_nos
    (each time setting $_ to the current element of @seq_nos). Each
    evaluation of the block is then added to %seq_nos_set. Therefore
    %seq_nos_set will be a hash (which is a list of key/value pairs) where
    all the keys are elements of @seq_nos, and all the values are 1.

    Paul Lalli
    Paul Lalli, Sep 28, 2005
    #3
  4. yezi <> wrote:


    > what is {$_=> 1 } mean?



    It means the same as

    {$_, 1 }


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Sep 28, 2005
    #4
  5. A. Sinan Unur <> wrote:

    > my %seq_nos_set = map{$_ => 1} @seq_nos;
    >
    > is another way of writing:
    >
    > my %seq_nos_set;
    > $seq_nos_set{$_} = 1 for @seq_nos;



    @seq_nos_set{@seq_nos} = (1) x @seq_nos;

    is the way I tend to write something like this. I'm not sure exactly
    WHY I got into that habit, though.
    David K. Wall, Sep 28, 2005
    #5
  6. "David K. Wall" <> wrote in
    news:Xns96DF6572239CAdkwwashere@216.168.3.30:

    > A. Sinan Unur <> wrote:
    >
    >> my %seq_nos_set = map{$_ => 1} @seq_nos;
    >>
    >> is another way of writing:
    >>
    >> my %seq_nos_set;
    >> $seq_nos_set{$_} = 1 for @seq_nos;

    >
    >
    > @seq_nos_set{@seq_nos} = (1) x @seq_nos;
    >
    > is the way I tend to write something like this. I'm not sure exactly
    > WHY I got into that habit, though.


    I find it very visually appealing. That might explain it :)

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Sep 28, 2005
    #6
  7. Tad McClellan <> writes:
    > yezi <> wrote:
    >> what is {$_=> 1 } mean?

    >
    >
    > It means the same as
    >
    > {$_, 1 }


    Every now and then I learn something new about Perl that is so basic.
    I had mentally tagged => as "quote LHS, and then act as comma"; your
    comment prompted me to look up perlop, which said,

    If the argument on the left is not a word, it is first
    interpreted as an expression, and then the string value
    of that is used.

    It's always nice when I can learn something new about something I
    thought I understood already.

    -=Eric
    Eric Schwartz, Sep 28, 2005
    #7
  8. yezi

    T Beck Guest

    Paul Lalli wrote:
    > { } indicates a block
    > => is a fancy way of writing a comma
    >
    > So { $_ => 1 } is a block that returns a 2-element list ($_, 1)



    Forgive me if I'm wrong, but in this case, wouldn't {} refer to an
    anonymous hash?

    --T Beck
    T Beck, Sep 28, 2005
    #8
  9. "T Beck" <> writes:
    > Paul Lalli wrote:
    >> { } indicates a block
    >> => is a fancy way of writing a comma
    >>
    >> So { $_ => 1 } is a block that returns a 2-element list ($_, 1)

    >
    > Forgive me if I'm wrong, but in this case, wouldn't {} refer to an
    > anonymous hash?


    This is in the context of the map function, so you should look at

    perldoc -f map

    To verify your assumption is correct.

    map BLOCK LIST
    map EXPR,LIST

    So map takes either a BLOCK or an EXPR, and in this case it's a block.

    "Wait a second," I hear you saying. "Doesn't { ... } make a hashref?"

    Yes, it does-- but it also makes a block. Consider this:

    sub foo
    {
    print "Hi, mom!\n";
    }

    Do the { } there make a hashref? No. Why? Because Perl can usually
    tell whether you want a block or not. Offhand I can't think of a case
    where it's ambiguous, but I'm sure someone else can.

    -=Eric
    Eric Schwartz, Sep 28, 2005
    #9
  10. yezi

    Paul Lalli Guest

    T Beck wrote:
    > Paul Lalli wrote:
    > > { } indicates a block
    > > => is a fancy way of writing a comma
    > >
    > > So { $_ => 1 } is a block that returns a 2-element list ($_, 1)

    >
    > Forgive me if I'm wrong, but in this case, wouldn't {} refer to an
    > anonymous hash?


    Only when you (rather rudely, IMHO) snip the appropriate context.

    my %hash = map { $_ => 1 } @foo;

    { $_ => 1 } is the block (or anonymous subroutine) that's passed as the
    first argument to map. This block returns a two element list.

    If the code was something along the lines of
    my $hash_ref = { $_ => 1 };

    then the braces would, indeed, create an anonymous hashref.

    map()'s prototype, effectively, is:
    sub map(&@);
    which, perldoc perlsub tells us: "An & requires an anonymous
    subroutine, which, if passed as the first argument, does not require
    the sub keyword or a subsequent comma"

    For more information:
    perldoc -f map

    Paul Lalli
    Paul Lalli, Sep 28, 2005
    #10
  11. yezi

    Guest

    Eric Schwartz <> wrote:
    > "T Beck" <> writes:
    > > Paul Lalli wrote:
    > >> { } indicates a block
    > >> => is a fancy way of writing a comma
    > >>
    > >> So { $_ => 1 } is a block that returns a 2-element list ($_, 1)

    > >
    > > Forgive me if I'm wrong, but in this case, wouldn't {} refer to an
    > > anonymous hash?

    >
    > This is in the context of the map function, so you should look at
    >
    > perldoc -f map
    >
    > To verify your assumption is correct.
    >
    > map BLOCK LIST
    > map EXPR,LIST
    >
    > So map takes either a BLOCK or an EXPR, and in this case it's a block.
    >
    > "Wait a second," I hear you saying. "Doesn't { ... } make a hashref?"
    >
    > Yes, it does-- but it also makes a block. Consider this:
    >
    > sub foo
    > {
    > print "Hi, mom!\n";
    > }
    >
    > Do the { } there make a hashref? No. Why? Because Perl can usually
    > tell whether you want a block or not. Offhand I can't think of a case
    > where it's ambiguous, but I'm sure someone else can.


    I'm not sure what you mean about being ambiguous. Before perl
    disambiguates the construct, it is always ambiguous. After it does so, it
    is never ambiguous (but it might be wrong). The interesting thing is, it
    guesses what you want before looking at the (lack of) comma.

    map {$_=>1} @data;
    block.

    map {$_=>1}, @data;
    block, syntax error (but if it disambiguated to hashref, then would not be
    syntax error

    map +{$_=>1}, @data;
    hash ref.

    map +{$_=>1} @data;
    hash ref, syntax error





    >
    > -=Eric


    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Sep 28, 2005
    #11
  12. yezi

    T Beck Guest

    Paul Lalli wrote:
    > T Beck wrote:
    > > Paul Lalli wrote:
    > > > { } indicates a block
    > > > => is a fancy way of writing a comma
    > > >
    > > > So { $_ => 1 } is a block that returns a 2-element list ($_, 1)

    > >
    > > Forgive me if I'm wrong, but in this case, wouldn't {} refer to an
    > > anonymous hash?

    >
    > Only when you (rather rudely, IMHO) snip the appropriate context.


    Sorry about the rudeness, I snipped it that way because I thought you
    were trying to draw attention to the {$_=>1} {without} the map in
    front. Deconstructing the problem, as it were.. No offense intended.

    > my %hash = map { $_ => 1 } @foo;
    >
    > { $_ => 1 } is the block (or anonymous subroutine) that's passed as the
    > first argument to map. This block returns a two element list.
    >
    > If the code was something along the lines of
    > my $hash_ref = { $_ => 1 };
    >
    > then the braces would, indeed, create an anonymous hashref.
    >
    > map()'s prototype, effectively, is:
    > sub map(&@);
    > which, perldoc perlsub tells us: "An & requires an anonymous
    > subroutine, which, if passed as the first argument, does not require
    > the sub keyword or a subsequent comma"
    >
    > For more information:
    > perldoc -f map



    Thanks for clearing that up. I had a feeling that I was missing
    something, but every once in a while I get lucky and get something
    right. This wasn't one of those times tho. Thanks to Xho and Eric for
    their responses, as well. Quite insightful.

    --T Beck
    T Beck, Sep 28, 2005
    #12
  13. writes:
    > Eric Schwartz <> wrote:
    >> Do the { } there make a hashref? No. Why? Because Perl can usually
    >> tell whether you want a block or not. Offhand I can't think of a case
    >> where it's ambiguous, but I'm sure someone else can.

    >
    > I'm not sure what you mean about being ambiguous. Before perl
    > disambiguates the construct, it is always ambiguous. After it does so, it
    > is never ambiguous (but it might be wrong).


    Well, I'd hope so, or it wouldn't be disambiguating, would it? :) I
    meant that as far as I know, Perl will always decide it's one thing or
    t'other; I don't know of any situation where Perl will give up and
    say, "I don't know if I should treat this as a code block or a
    hashref."

    -=Eric
    Eric Schwartz, Sep 28, 2005
    #13
  14. In article <Xns96DF6572239CAdkwwashere@216.168.3.30>, says...
    >
    >
    >A. Sinan Unur <> wrote:
    >
    >> my %seq_nos_set = map{$_ => 1} @seq_nos;
    >>
    >> is another way of writing:
    >>
    >> my %seq_nos_set;
    >> $seq_nos_set{$_} = 1 for @seq_nos;

    >
    >
    > @seq_nos_set{@seq_nos} = (1) x @seq_nos;


    For me, this has two drawbacks:

    1. It gets clumsy with strict:

    my @seq_nos_set{@seq_nos} = (1) x @seq_nos;

    gives Syntax error. One needs:

    my %seq_nos_set;
    @seq_nos_set{@seq_nos} = (1) x @seq_nos;

    2. With a constant list you won't know the count:

    @seq_nos_set{qw(foo bar hinz kunz)} = (1) x 100;

    Any other elegant ways to create such hashes?

    Greetings

    Heinrich

    --
    Heinrich Mislik
    Zentraler Informatikdienst der Universitaet Wien
    A-1010 Wien, Universitaetsstrasse 7
    Tel.: (+43 1) 4277-14056, Fax: (+43 1) 4277-9140
    Heinrich Mislik, Sep 29, 2005
    #14
  15. yezi

    Guest

    Heinrich Mislik wrote:
    > In article <Xns96DF6572239CAdkwwashere@216.168.3.30>, says...
    > >
    > >
    > >A. Sinan Unur <> wrote:
    > >
    > >> my %seq_nos_set = map{$_ => 1} @seq_nos;
    > >>
    > >> is another way of writing:
    > >>
    > >> my %seq_nos_set;
    > >> $seq_nos_set{$_} = 1 for @seq_nos;

    > >
    > >
    > > @seq_nos_set{@seq_nos} = (1) x @seq_nos;

    >
    > For me, this has two drawbacks:
    >
    > 1. It gets clumsy with strict:
    >
    > my @seq_nos_set{@seq_nos} = (1) x @seq_nos;
    >
    > gives Syntax error. One needs:
    >
    > my %seq_nos_set;
    > @seq_nos_set{@seq_nos} = (1) x @seq_nos;
    >
    > 2. With a constant list you won't know the count:
    >
    > @seq_nos_set{qw(foo bar hinz kunz)} = (1) x 100;
    >
    > Any other elegant ways to create such hashes?
    >


    my %seq_nos_set = map { ($_, 1) } @seq_nos;

    # my %seq_nos_set = map { ($_, 1) } qw/foo bar hinz kunz/;



    --
    Charles DeRykus
    , Sep 29, 2005
    #15
  16. "" <> wrote in
    news::

    >
    > Heinrich Mislik wrote:
    >> In article <Xns96DF6572239CAdkwwashere@216.168.3.30>,
    >> says...
    >> >
    >> >
    >> >A. Sinan Unur <> wrote:
    >> >
    >> >> my %seq_nos_set = map{$_ => 1} @seq_nos;
    >> >>
    >> >> is another way of writing:
    >> >>
    >> >> my %seq_nos_set;
    >> >> $seq_nos_set{$_} = 1 for @seq_nos;
    >> >
    >> >
    >> > @seq_nos_set{@seq_nos} = (1) x @seq_nos;

    >>
    >> For me, this has two drawbacks:
    >>
    >> 1. It gets clumsy with strict:
    >>
    >> my @seq_nos_set{@seq_nos} = (1) x @seq_nos;
    >>
    >> gives Syntax error. One needs:
    >>
    >> my %seq_nos_set;
    >> @seq_nos_set{@seq_nos} = (1) x @seq_nos;
    >>
    >> 2. With a constant list you won't know the count:
    >>
    >> @seq_nos_set{qw(foo bar hinz kunz)} = (1) x 100;
    >>
    >> Any other elegant ways to create such hashes?
    >>

    >
    > my %seq_nos_set = map { ($_, 1) } @seq_nos;


    Oh my, a perfect circle. Spooky!

    Sinan
    A. Sinan Unur, Sep 29, 2005
    #16
  17. yezi

    Bart Lateur Guest

    yezi wrote:

    >%seq_nos_set=map{$_=> 1} @seq_nos


    >what is {$_=> 1 } mean?


    It is a block of code that returns a list of two items:

    ($_, 1)

    So for each item in the source list, this block is called, with $_ the
    value of the current item, and this block returns a list with these two
    values for each item. In the end, map will return a total list with 2
    times as many items as the source list.

    HTH,
    Bart.
    Bart Lateur, Sep 29, 2005
    #17
  18. yezi

    Guest

    A. Sinan Unur wrote:
    > "" <> wrote in
    > news::
    >
    > >
    > > Heinrich Mislik wrote:
    > >> In article <Xns96DF6572239CAdkwwashere@216.168.3.30>,
    > >> says...
    > >> >
    > >> >
    > >> >A. Sinan Unur <> wrote:
    > >> >
    > >> >> my %seq_nos_set = map{$_ => 1} @seq_nos;
    > >> >>
    > >> >> is another way of writing:
    > >> >>
    > >> >> my %seq_nos_set;
    > >> >> $seq_nos_set{$_} = 1 for @seq_nos;
    > >> >
    > >> >
    > >> > @seq_nos_set{@seq_nos} = (1) x @seq_nos;
    > >>
    > >> ...

    > >
    > > my %seq_nos_set = map { ($_, 1) } @seq_nos;

    >
    > Oh my, a perfect circle. Spooky!


    Those who do not remember threads are doomed to repeat them...

    --
    Charles DeRykyus
    , Sep 30, 2005
    #18
  19. yezi

    Bart Lateur Guest

    Heinrich Mislik wrote:

    >2. With a constant list you won't know the count:
    >
    >@seq_nos_set{qw(foo bar hinz kunz)} = (1) x 100;
    >
    >Any other elegant ways to create such hashes?


    my %seq_nos_set;
    $seq_nos_set{$_} = 1 foreach qw(foo bar hinz kunz);

    --
    Bart.
    Bart Lateur, Sep 30, 2005
    #19
  20. yezi

    Bart Lateur Guest

    Eric Schwartz wrote:

    >Well, I'd hope so, or it wouldn't be disambiguating, would it? :)


    But Perl occasionally *is* ambiguous. Witness this silly example:

    { $_ => 1 };

    Is this a block, or a hashref in void context?

    --
    Bart.
    Bart Lateur, Sep 30, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. srikanth
    Replies:
    5
    Views:
    278
    Richard Heathfield
    Feb 28, 2006
  2. Replies:
    7
    Views:
    327
  3. bolega
    Replies:
    31
    Views:
    892
  4. bolega
    Replies:
    157
    Views:
    2,400
  5. Steve
    Replies:
    3
    Views:
    197
    C.DeRykus
    Feb 24, 2010
Loading...

Share This Page