Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

How to find out if X is an element in an array?

by juahonen (Novice)
on Jan 26, 2000 at 17:07 UTC ( #2482=perlquestion: print w/replies, xml ) Need Help??

juahonen has asked for the wisdom of the Perl Monks concerning the following question: (arrays)

How to find out if X is an element in an array?

Originally posted as a Categorized Question.

  • Comment on How to find out if X is an element in an array?

Replies are listed 'Best First'.
Re: How to find out if X is an element in an array?
by Anonymous Monk on Feb 15, 2000 at 01:31 UTC
    Try this to search for the presence of an element in an array.
    my $element = 'Whatever you are searching for' ; if (grep {$_ eq $element} @TheArray) { print "Element '$element' found!\n" ; }
Re: How to find out if X is an element in an array?
by Corion (Pope) on Jun 27, 2000 at 18:29 UTC

    The other answers are all cool for arrays, but maybe using an array is wrong in the first place. Perl has a data type specialized for fast lookups, the hash (denoted by a % in front of the variable name). A lookup of an element in a hash is very fast, while grep and the likes have to go through the whole array, which is slower.

    There are some drawbacks to hashes as well, first, they require you to change your code and second and more importantly, a hash dosen't preserve the order of elements - you can't get the elements back from the hash in the order you put them into the hash.

    If the above drawbacks are no problem with you, you might want to use the following code :

    #!/usr/bin/perl -w use strict; my %elements; my $element = "foo"; # Fill up our hash a bit foreach ("bla", "blubb", "foo", "bah") { $elements{$_} = 1; }; # now check if $element is in our hash : print "Found '$element'\n" if (exists $elements{$element}); print "D'oh - '$element' not found\n" unless (exists $elements{$elem +ent}); # You can still get to all elements in %elements : foreach (keys %elements) { # but they are in some weird order ... print "$_\n"; };
Re: How to find out if X is an element in an array?
by davido (Cardinal) on Oct 01, 2003 at 07:56 UTC
    Yet Another Way....

    You can use a temporary hash to build up the values contained in @array as hash keys. It then becomes trivial to check the existance of a key. You pay a price in speed and memory by copying the array to a hash, but you gain some speed and flexibility later on as you search for the existance of a particular item. Hash key lookups are, themselves, fast. That gain in speed and flexibility grows the more times you find yourself checking existances.

    Here's the example code:

    my @array = qw/This that the other and then some./; my %hash; @hash{@array}=(); my $look_for = "other"; print "'$look_for' exists\n" if exists $hash{$look_for};

    If you're only looking for one thing, use one of the methods above. If you're looking again and again, this one is not too bad. You're not concerned that duplicate items within @array aren't preserved, because you're just using the hash to determine whether a particular item exists at least once. If you care about number of times, you can modify this approach so that the count is contained as the value matched to the key.

Re: How to find out if X is an element in an array?
by little_mistress (Monk) on Apr 01, 2000 at 04:30 UTC
    You could do it like this:
    my $element = "catchme"; my @array = ( "catchme", "if", "you", "can" ); if ( @found = grep { $_ eq $element } @array ) { my $found = join ",", @found; print "Here's what we found: $found\n"; } else { print "Sorry, \"$element\" not found in \@array\n"; }
    I know that's a little longer than other answers but, I think this gives a little more detail and is easier to see how it works.
      In most cases my should be used for declaration of variables instead of local. In most cases lexically scoped variables are more appropriative. See perlsub for details.

      --
      Ilya Martynov (http://martynov.org/)

Re: How to find out if X is an element in an array?
by Roger (Parson) on Sep 10, 2003 at 03:21 UTC
    $X = "x"; @array = qw / x y z 1 2 3 /; return exists {map { $_ => 1 } @array}->{$X};
    The above code returns 1 if element found, undef if not found.
      Hmm - This method will not scale well because it creates a temporary hash. If this is a repeated search in a large array, you would be doing a lot of memory management.

      Here is the equivalent code, using grep:

      $X = "x"; @array = qw / x y z 1 2 3 /; return scalar grep(/^$X$/,@array) > 0;
      The "scalar" isnt really necessary, but it documents the fact that grep is called in a scalar context.
Re: How to find out if X is an element in an array?
by mascip (Pilgrim) on May 22, 2013 at 12:06 UTC

    This blog post discusses the best answers to this question.

    As a short summary, if you can install CPAN modules then the best solutions are:

    if any(@ingredients) eq 'flour';
    or
    if @ingredients->contains('flour');
    However, a more usual idiom is:
    if any { $_ eq 'flour' } @ingredients
    which i find less clear.

    But please don't use the first() function! It doesn't express the intent of your code at all. Don't use the "Smart match" operator: it is broken. And don't use grep() nor the solution with a hash: they iterate through the whole list. While any() will stop as soon as it finds your value.
    Check out the blog post for more details.

    PS: i'm answering for people who will have the same question in the future.

Re: How to find out if X is an element in an array?
by guha (Priest) on Nov 25, 2010 at 17:18 UTC
    #!perl use strict; use warnings; use List::MoreUtils qw{ any }; my @array = qw{ A B C D E X }; if (any { $_ eq 'X'} @array) { print 'YES'; } else { print 'NO'; }
Re: How to find out if X is an element in an array?
by linuxkid (Sexton) on Jun 22, 2012 at 21:44 UTC
Re: How to find out if X is an element in an array?
by aarons (Initiate) on Nov 18, 2010 at 10:44 UTC
    succinctly:
    print grep { $_ eq $value } @list_of_values ? "present\n" : "absent\n";
Re: How to find out if X is an element in an array?
by russmann (Initiate) on Dec 08, 2001 at 02:30 UTC
    Here is a super-fast script i just wrote using this information. It's for finding email addresses (elements) in one file that aren't in another.
    #!/usr/bin/perl # File definitions $file1 = "first_file.txt"; # File with emails that might be duplicated + on 2nd file $file2 = "second_file.txt"; # These emails have already been used. $file3 = "finalemails.txt"; # Final product - emails that havn't been +used yet. # Load arrays with file contents open(FILE, "<$file1") || die "Can't open $file1\n"; @updatelist = <FILE>; close(FILE); open(FILE, "<$file2") || die "Can't open $file2\n"; @storelist = <FILE>; close(FILE); # Set %elements hash to 1 for each address in store list. foreach (@storelist) { $elements{$_} = 1; }; # Loop to create the final array of emails foreach $update(@updatelist) { if (!find_in_store($update)) { push @finallist, $update; } } # Write final array to file open(FILE, ">$file3") || die "Can't open $file3\n"; print FILE @finallist; close(FILE); # Routine to check for existance of an address. sub find_in_store { $element = $_[0]; if (exists $elements{$element}) { return(1); } else { return (0); } }

      This may be simplistic, but what about the following code. Anyone?

      # # Given: first value passed is the element to check for # Given: remaining values are the array to check in # sub find_in_list { my ($element, @list2check) = @_; return(scalar(grep($element, @updatelist))); }
        Do this or if you search for "1" it'll find "1" as well as "123"...
        return(scalar(grep(/^$element$/, @updatelist)));
        -julian geek
      Is it safer to undef FILE before you reuse it or does it make a difference? I know from a readability standpoint, you might consider using different handles:
      open(FILE1, "<$file1") || die "Can't open $file1\n"; open(FILE2, "<$file2") || die "Can't open $file1\n"; open(EMFILE, "<$file3") || die "Can't open $file1\n";
      I guess from the efficiency point of view that it would use less memory if you either use the same file handle or undef them after you close the file. Is that true?

      Sparky
      Here's a similar approach:
      # snip my %hash; $hash{$_}=1 for (@updatelist); $hash{$_}=0 for (@storelist); for (keys %hash) { push @finallist, $_ if ($hash{$_}); }
      ie: "make list of new addresses, but cross off those already used".

      ..02

      cLive ;-)

Re: How to find out if X is an element in an array?
by rajib (Novice) on Aug 20, 2002 at 17:31 UTC
    $X = "x"; @array = ("y", "z", "x"); $i = 0; while (($i <= $#array && ($array[$i] ne $X)) { ++$i; } if ($i <= $#array) { # searched it & eureka return 1; # for true; } return 0; # for false;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://2482]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2021-09-17 21:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?