Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

using map

by Anonymous Monk
on May 05, 2012 at 21:50 UTC ( #969088=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

hi guys, just wondering how i'd go about pushing digits in to an array using map.. i guessed it would go something like this:
@digits = map { $_ =~ m/[0-9]/g ? $_ : () } $list;
any ideas? thanks :)

Replies are listed 'Best First'.
Re: using map
by GrandFather (Sage) on May 05, 2012 at 22:41 UTC

    You could set an array using something like that, but if you want to add extra stuff to the end of the array (that's what push does) you actually need to use push.

    Use grep to select elements from a list. Although it is possible to abuse map in the way you showed to achieve that it really isn't what map is about.

    $list is not a list (except in the degenerate sense of a list with only one element), it is a scalar. It may be that it is a reference to an array, but in that case you'd need to write @$list to make the referenced list of elements available for a grep or map.

    If you have some code that isn't doing what you expect, how about you show us a runnable sample script to illustrate the problem? Combining the code snippet you show and your question you seem to have at least three misunderstandings about what is going on in relation to that code!

    True laziness is hard work
Re: using map
by AnomalousMonk (Chancellor) on May 05, 2012 at 22:13 UTC

    One could use map as in
        my @digits = map { $_ =~ m{ \d }xmsg } $list;
    but it would be, IMHO, simpler, clearer and more idiomatic as

    >perl -wMstrict -le "my $list = '1, 23-456 7890'; my @digits = $list =~ m{ \d }xmsg; printf qq{'$_' } for @digits; " '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'

    (Although, to echo JavaFan, it's not really clear just what you want.)

      printf qq{'$_' } for @digits;

      The correct format for printf is printf FORMAT_STRING, LIST so that should be:

      printf q{'%s' }, $_ for @digits;

      But you don't really need the extra overhead of using printf:

      print qq{'$_' } for @digits;

      But that wouldn't work properly because of your use of the -l switch which will add a newline after every print.    Of course you could do something like this:

      print join ' ', map "'$_'", @digits;

      Which also avoids the extra space character at the end of the line.

        The correct format for printf is printf FORMAT_STRING, LIST so that should be:

        Any ordinary (non-specifier) characters in the format string are output verbatim.

        If the format contains no %specifiers, then just what is in the template gets output.

        As -l doesn't affect printf, it makes it a convenient way of printing output that does not get an automatic \n appended for those rare occasions when that is required.

        It is convenient, safe and a lot easier than having to add \n to every darn print statement.

        Of course, say ought to be a simple alternative to -l, but a) they made it so darn inconvenient to use; b) its a pain in the neck having to switch back to print any time you need to test something under a pre-5.10 version.

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?

        The correct format for printf ...
        ... wouldn't work properly because of your use of the -l switch ...

        The -l switch is hard-wired into the little command-line code formatter I use because I never got around to making the various switches, module inclusions, etc., optional. It's on my to-do list. As a consequence, as you point out, the use of  print() would have given me a 'vertical' listing, which I did not want. Instead of tediously editing out the -l every time I tested an example, I just used  printf() even though it's just a tad inappropriate.

        Which also avoids the extra space character at the end of the line.

        I was feeling wildly extravagant when I wrote the example code.

Re: using map
by tobyink (Abbot) on May 05, 2012 at 22:22 UTC

    By "push" do you mean that @digits already contains some data, and you want to append some extra stuff (digits) to it? If so...

    push @digits, map { /[0-9]/ ? $_ : () } @list

    But better than map would be grep.

    push @digits, grep { /[0-9]/ } @list;
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: using map
by JavaFan (Canon) on May 05, 2012 at 22:01 UTC
    Something like that, yeah. It looks like a grep to me. But we don't know what you are getting, and we don't know what you were expecting, so don't expect more from us than confirming your "something like this".

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://969088]
Approved by tobyink
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2018-01-17 18:08 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (203 votes). Check out past polls.