Testing against a list of values ?

Discussion in 'Perl Misc' started by - Bob -, Apr 5, 2007.

  1. - Bob -

    - Bob - Guest

    I coded the following, which works but is lengthy:

    if ( ($temp ne "a")
    and( $temp ne "x" )
    and ( $temp ne "y" ) ){ ....}

    What's a more Perl-like and compact way to code something like this ?
    - Bob -, Apr 5, 2007
    #1
    1. Advertising

  2. - Bob - wrote:
    > I coded the following, which works but is lengthy:
    >
    > if ( ($temp ne "a")
    > and( $temp ne "x" )
    > and ( $temp ne "y" ) ){ ....}
    >
    > What's a more Perl-like and compact way to code something like this ?


    Check out the grep() function.

    perldoc -f grep

    if ( grep( $temp eq $_, @values ) == 0 ) { ... }

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Apr 5, 2007
    #2
    1. Advertising

  3. - Bob -

    Uri Guttman Guest

    >>>>> "PG" == Purl Gurl <> writes:

    PG> Bob wrote:
    >> I coded the following, which works but is lengthy:


    >> if ( ($temp ne "a") and( $temp ne "x" )
    >> and ( $temp ne "y" ) ){ ....}


    >> What's a more Perl-like and compact way to code something like this ?


    PG> #!perl

    PG> while (<DATA>)
    PG> {
    PG> if ($_ =~ tr/axy// == 0)
    PG> { print $_; }
    PG> }

    as usual moronzilla gets it wrong. try that code with 'ax' or any string
    of length > 1 and at least one of 'axy'. it won't behave as the OP
    wants.

    the correct answer is to use a hash. plenty of examples in this group so
    search it with google.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Apr 5, 2007
    #3
  4. - Bob -

    Uri Guttman Guest

    >>>>> "PG" == Purl Gurl <> writes:

    PG> Uri Guttman wrote:
    >> Purl Gurl wrote:
    >>> Bob wrote:


    >>>> I coded the following, which works but is lengthy:


    >>>> if ( ($temp ne "a") and( $temp ne "x" )
    >>>> and ( $temp ne "y" ) ){ ....}


    >>>> What's a more Perl-like and compact way to code something like this ?


    >>> #!perl


    >>> while (<DATA>)
    >>> {
    >>> if ($_ =~ tr/axy// == 0)
    >>> { print $_; }
    >>> }


    >> as usual moronzilla gets it wrong. try that code with 'ax' or any string
    >> of length > 1 and at least one of 'axy'. it won't behave as the OP
    >> wants.


    PG> Irrelevant. Your comments do not comply with the originating author's
    PG> stated parameters. You are practicing deceit, more succinct, you are
    PG> lying to readers which is much in keeping with your years long history
    PG> and reputation as being amongst the worst of trolls spreading ignorance
    PG> and discontent within this discussion group.

    he never stated that the input would always be a single character. you
    assumed so in your broken code. so your code is wrong as it usually is
    as it doesn't account for bad data. it does account for bad code as it
    came from you.

    as for trolling and such, when have you last published a cpan module,
    gave a talk at a conference, been hired to train people in perl or any
    of a number of perl things? not in anyone's lifetime here. so please go
    back to your loonie been as you did for a blessed few months.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Apr 5, 2007
    #4
  5. Gunnar Hjalmarsson, Apr 5, 2007
    #5
  6. On Apr 4, 6:15 pm, Purl Gurl <> wrote:
    > Uri Guttman wrote:
    > > Purl Gurl wrote:
    > >> Uri Guttman wrote:
    > >>> Purl Gurl wrote:
    > >>>> Bob wrote:

    >
    > (snipped)
    >
    >
    >
    > >>> as usual moronzilla gets it wrong. try that code with 'ax' or any string
    > >>> of length > 1 and at least one of 'axy'. it won't behave as the OP
    > >>> wants.
    > >> Irrelevant. Your comments do not comply with the originating author's
    > >> stated parameters. You are practicing deceit, more succinct, you are
    > >> lying to readers which is much in keeping with your years long history
    > >> and reputation as being amongst the worst of trolls spreading ignorance
    > >> and discontent within this discussion group.

    > > he never stated that the input would always be a single character. you
    > > assumed so in your broken code. so your code is wrong as it usually is
    > > as it doesn't account for bad data. it does account for bad code as it
    > > came from you.
    > > as for trolling and such, when have you last published a cpan module,
    > > gave a talk at a conference, been hired to train people in perl or any
    > > of a number of perl things? not in anyone's lifetime here. so please go
    > > back to your loonie been as you did for a blessed few months.

    >
    > "loony bin"
    >
    > Ha! Ha! You are so predictable, such a comical bozo troll!
    >
    > You are THE laughing stock of the Perl community and have
    > been so, for many years.
    >


    I know I shouldn't interject, however, Uri knows what he is talking
    about, you don't. Besides, a simple google search on Uri shows that he
    is pretty well respected in the Perl community.
    grocery_stocker, Apr 5, 2007
    #6
  7. - Bob -

    Mirco Wahab Guest

    - Bob - wrote:
    > I coded the following, which works but is lengthy:
    >
    > if ( ($temp ne "a")
    > and( $temp ne "x" )
    > and ( $temp ne "y" ) ){ ....}
    >
    > What's a more Perl-like and compact way to code something like this ?


    Depending on your real intend (check only
    characters - or longer strings), I'd saythat 'grep'
    would be 'perlish' (solution already posted by others)

    You could make it 'more descriptive' by wrapping it
    into a subroutine, like

    ...

    sub NOT_IN { ! grep $_[0] =~ /$_/, @_[1..@_-1] }


    my $temp ="bz";

    if ( NOT_IN $temp => qw' a x y ' ) {
    print "$temp doesn't contain one\n"
    # ....
    }

    ...


    Regards

    M.
    Mirco Wahab, Apr 5, 2007
    #7
  8. - Bob -

    Dr.Ruud Guest

    - Bob - schreef:

    > I coded the following, which works but is lengthy:
    >
    > if ( ($temp ne "a")
    > and( $temp ne "x" )
    > and ( $temp ne "y" ) ){ ....}
    >
    > What's a more Perl-like and compact way to code something like this ?


    For example

    /^[axy]$/

    or

    /^(?:a|x|y)$/

    where the latter has room for longer values. You can mix'm too:

    if ( $temp =~ m!^(?: [ny] | no | yes )$!x ) {...}

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Apr 5, 2007
    #8
  9. - Bob -

    Uri Guttman Guest

    >>>>> "MD" == Michele Dondi <> writes:

    MD> On Thu, 05 Apr 2007 01:58:15 +0200, Gunnar Hjalmarsson
    MD> <> wrote:

    >> if ( grep( $temp eq $_, @values ) == 0 ) { ... }


    MD> unless ( grep $temp eq $_, @values) { ... }

    MD> But seriously, in this case hash look up is probably better...

    MD> (too bad there's not a syntactically sweet enough way to make an array
    MD> or a list into a hash(ref) with, say, undef values. In this case I can
    MD> think of

    MD> unless ( { map { $_ => 1 } @values}->{$temp} ) { ... } # )

    and that rebuilds the anon hash each time which is not nice if it is
    called more than once. maybe in a cgi or single shot script it would be
    ok.

    a simple way to make a hash of keys with undef values is:

    my %isa_foo ;
    @isa_foo{ @values } = () ;

    i think i have seen tricks (randal?) on how to merge those line and i
    bet abigail or damian could do it with an anon hash. but that is getting
    to wacky for my taste. whenever i have a list of things to test against,
    i usually need the list as an array too so making an array of foo and a
    hash of isa_foo is best IMO (michele: see, i shifted there!)

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Apr 5, 2007
    #9
  10. - Bob -

    Uri Guttman Guest

    >>>>> "MD" == Michele Dondi <> writes:

    MD> On Thu, 05 Apr 2007 10:54:28 -0400, Uri Guttman <>
    MD> wrote:

    >> and that rebuilds the anon hash each time which is not nice if it is
    >> called more than once. maybe in a cgi or single shot script it would be
    >> ok.
    >>
    >> a simple way to make a hash of keys with undef values is:
    >>
    >> my %isa_foo ;
    >> @isa_foo{ @values } = () ;


    MD> Yes, yes, yes. I don't feel a *compelling* need for such a beast as
    MD> that I hinted to in the other post. But occasionally I miss it.
    MD> Precisely when I *want* to check if if a single value is in a list,
    MD> and want to do so *only once*, possibly in one *single statement*.

    MD> Well, a situation that springs to mind is this: the other day I wanted
    MD> to check if a coderef is lvalue'd but attributes::get() returns a list
    MD> of the attributes defined on a ref, so I'm exactly under the
    MD> circumstances described above. Basically I may want something short
    MD> enough to be used as in

    MD> if ( islvalued($ref) ) { ... }

    then List::Util::first is your friend. building a temp hash from a list
    and then looking it up is at least O(N) (more caps!) as it has to scan
    all the keys. first is O(N) but will scan on average only half of the
    keys.

    if ( first { $_ eq 'lvalue' } attributes::get($ref) ) { ... }

    the hash test is almost always better when you check it more than
    once. and as i said i use it if i have the list of keys in advance since
    saying $isa_foo{$key} is nice and readable.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Apr 5, 2007
    #10
  11. Uri Guttman wrote:
    > a simple way to make a hash of keys with undef values is:
    >
    > my %isa_foo ;
    > @isa_foo{ @values } = () ;
    >
    > i think i have seen tricks (randal?) on how to merge those line


    my %isa_foo = map { $_ => undef } @values;

    Is that a trick? ;-)

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Apr 5, 2007
    #11
  12. - Bob -

    Uri Guttman Guest

    >>>>> "GH" == Gunnar Hjalmarsson <> writes:

    GH> Uri Guttman wrote:
    >> a simple way to make a hash of keys with undef values is:
    >> my %isa_foo ;
    >> @isa_foo{ @values } = () ;
    >> i think i have seen tricks (randal?) on how to merge those line


    GH> my %isa_foo = map { $_ => undef } @values;

    GH> Is that a trick? ;-)

    nope. i know that map idea from way back and mention it in my article on
    hash slices. the wacky trick was doing that for an anon hash or some
    other thing that needed strange ref munging. it was very fugly but
    amusing and i can't recall who posted it nor would i know how to search
    for it easily. not a problem since i wouldn't use that wacko code in
    production.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Apr 5, 2007
    #12
  13. - Bob -

    Guest

    Uri Guttman <> wrote:
    > >>>>> "GH" == Gunnar Hjalmarsson <> writes:

    >
    > GH> Uri Guttman wrote:
    > >> a simple way to make a hash of keys with undef values is:
    > >> my %isa_foo ;
    > >> @isa_foo{ @values } = () ;
    > >> i think i have seen tricks (randal?) on how to merge those line

    >
    > GH> my %isa_foo = map { $_ => undef } @values;
    >
    > GH> Is that a trick? ;-)
    >
    > nope. i know that map idea from way back and mention it in my article on
    > hash slices. the wacky trick was doing that for an anon hash or some
    > other thing that needed strange ref munging. it was very fugly but
    > amusing and i can't recall who posted it nor would i know how to search
    > for it easily. not a problem since i wouldn't use that wacko code in
    > production.


    Perhaps something like this:

    @$_{@values}=() foreach (\my %$isa_foo);

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Apr 6, 2007
    #13
  14. - Bob -

    Dr.Ruud Guest

    Uri Guttman schreef:

    > a simple way to make a hash of keys with undef values is:
    >
    > my %isa_foo ;
    > @isa_foo{ @values } = () ;



    IIRC there was a difference between the result of that and this:

    my %isa_foo ;
    @isa_foo{ @values } = () x @values ;

    (undef as status and undef as value)

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Apr 6, 2007
    #14
  15. - Bob -

    Uri Guttman Guest

    >>>>> "R" == Ruud <> writes:

    R> Uri Guttman schreef:
    >> a simple way to make a hash of keys with undef values is:
    >>
    >> my %isa_foo ;
    >> @isa_foo{ @values } = () ;


    R> IIRC there was a difference between the result of that and this:

    R> my %isa_foo ;
    R> @isa_foo{ @values } = () x @values ;

    R> (undef as status and undef as value)

    yep. you can tell the difference in the amount of storage used and
    probably with some internal probing with a scalar::util func or
    something.

    a hash entry can be totally empty and it will return an undef if
    accessed. or it can have a proper sv in the entry which is undef
    itself. i am not sure of any other direct way to get the undef slot but
    the assignment of an empty list to a slice. but there probably is one
    and i don't know it or some module can do it.

    and in both cases you test for a key in the set with exists. some like
    to assign 1 or some true value so they can just do a boolean test and
    drop the exists. either way is fine with me.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Apr 6, 2007
    #15
  16. - Bob -

    Uri Guttman Guest

    >>>>> "x" == xhoster <> writes:

    x> Uri Guttman <> wrote:
    >> >>>>> "GH" == Gunnar Hjalmarsson <> writes:

    >>

    GH> Uri Guttman wrote:
    >> >> a simple way to make a hash of keys with undef values is:
    >> >> my %isa_foo ;
    >> >> @isa_foo{ @values } = () ;
    >> >> i think i have seen tricks (randal?) on how to merge those line

    >>

    GH> my %isa_foo = map { $_ => undef } @values;
    >>

    GH> Is that a trick? ;-)
    >>
    >> nope. i know that map idea from way back and mention it in my article on
    >> hash slices. the wacky trick was doing that for an anon hash or some
    >> other thing that needed strange ref munging. it was very fugly but
    >> amusing and i can't recall who posted it nor would i know how to search
    >> for it easily. not a problem since i wouldn't use that wacko code in
    >> production.


    x> Perhaps something like this:

    x> @$_{@values}=() foreach (\my %$isa_foo);

    that looks like what i recall and you can see why i would never use it
    in production. :) it was to declare a scalar to hold a hash ref and
    assign boolean keys in one line.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Apr 6, 2007
    #16
  17. On 2007-04-06 00:31, Uri Guttman <> wrote:
    >>>>>> "R" == Ruud <> writes:

    >
    > R> Uri Guttman schreef:
    > >> a simple way to make a hash of keys with undef values is:
    > >>
    > >> my %isa_foo ;
    > >> @isa_foo{ @values } = () ;

    >
    > R> IIRC there was a difference between the result of that and this:
    >
    > R> my %isa_foo ;
    > R> @isa_foo{ @values } = () x @values ;
    >
    > R> (undef as status and undef as value)
    >
    > yep. you can tell the difference in the amount of storage used and
    > probably with some internal probing with a scalar::util func or
    > something.


    I can't see a difference with perl 5.8.0 or 5.8.8 on Linux:


    #!/usr/bin/perl
    use warnings;
    use strict;

    my %x;

    my (@a) = (1 .. $ARGV[1]);

    my $m0 = mem();
    if ($ARGV[0] eq '1') {
    @x{@a} = (1) x @a;
    } elsif ($ARGV[0] eq 'lx') {
    @x{@a} = () x @a;
    } elsif ($ARGV[0] eq 'le') {
    @x{@a} = ();
    }
    print mem() - $m0, "\n";

    sub mem {
    open(my $f, '<', "/proc/$$/status");
    while (<$f>) {
    return $1 if (/VmSize:\s+(\d+) kB/);
    }
    }

    yoyo:~/tmp 10:57 126% ./foo 1 100000
    10520
    yoyo:~/tmp 10:57 127% ./foo lx 100000
    9116
    yoyo:~/tmp 10:57 128% ./foo le 100000
    9116


    > and in both cases you test for a key in the set with exists. some like
    > to assign 1 or some true value so they can just do a boolean test and
    > drop the exists. either way is fine with me.


    Assigning 1 does take a bit more memory.

    hp


    --
    _ | Peter J. Holzer | Blaming Perl for the inability of programmers
    |_|_) | Sysadmin WSR | to write clearly is like blaming English for
    | | | | the circumlocutions of bureaucrats.
    __/ | http://www.hjp.at/ | -- Charlton Wilbur in clpm
    Peter J. Holzer, Apr 6, 2007
    #17
  18. - Bob -

    Uri Guttman Guest

    >>>>> "PJH" == Peter J Holzer <> writes:

    PJH> On 2007-04-06 00:31, Uri Guttman <> wrote:
    >>>>>>> "R" == Ruud <> writes:

    >>

    R> Uri Guttman schreef:
    >> >> a simple way to make a hash of keys with undef values is:
    >> >>
    >> >> my %isa_foo ;
    >> >> @isa_foo{ @values } = () ;

    >>

    R> IIRC there was a difference between the result of that and this:
    >>

    R> my %isa_foo ;
    R> @isa_foo{ @values } = () x @values ;
    >>

    R> (undef as status and undef as value)
    >>
    >> yep. you can tell the difference in the amount of storage used and
    >> probably with some internal probing with a scalar::util func or
    >> something.


    PJH> I can't see a difference with perl 5.8.0 or 5.8.8 on Linux:

    PJH> sub mem {
    PJH> open(my $f, '<', "/proc/$$/status");
    PJH> while (<$f>) {
    PJH> return $1 if (/VmSize:\s+(\d+) kB/);

    i wouldn't use a vmem thingy but try it with devel::size (iirc) which
    will tell you the actual ram used by a perl structure.

    >> and in both cases you test for a key in the set with exists. some like
    >> to assign 1 or some true value so they can just do a boolean test and
    >> drop the exists. either way is fine with me.


    PJH> Assigning 1 does take a bit more memory.

    so maybe it does use the undef flag in the hash entry in both cases. it
    would be a nice optimization. i just recall they did different things
    because of the generated code or whatever. in any case assigning an
    empty list will be faster than making a list of undefs with x or map.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Apr 6, 2007
    #18
    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. Michael Klatt
    Replies:
    2
    Views:
    362
    Pete Becker
    May 22, 2004
  2. bruce
    Replies:
    0
    Views:
    419
    bruce
    Feb 16, 2009
  3. Shen Weihui
    Replies:
    3
    Views:
    247
  4. Brent Collier

    Testing against an api

    Brent Collier, Jan 23, 2009, in forum: Ruby
    Replies:
    3
    Views:
    119
    Matt Todd
    Jan 24, 2009
  5. Michele Simionato

    Testing against multiple versions of Python

    Michele Simionato, Oct 19, 2012, in forum: Python
    Replies:
    3
    Views:
    189
    Michele Simionato
    Oct 19, 2012
Loading...

Share This Page