Loading ...
Sorry, an error occurred while loading the content.

Re: [PBML] easy way to find out if a variable is in an array?

Expand Messages
  • Andrew Johnson
    Mike Payne wrote: ! Or coming from a completely different side... You could just do this... ! ! $_ = join( ,@where_it_may_be); ! if (/$what_i_want/) { !
    Message 1 of 5 , Oct 26, 2000
    • 0 Attachment
      Mike Payne wrote:
      ! Or coming from a completely different side... You could just do this...
      !
      ! $_ = join(' ',@where_it_may_be);
      ! if (/$what_i_want/) {
      ! print "it's there";
      ! }

      Followed by this:

      ! I'd be interested in hearing everyone's thoughts about this way of solving
      ! the problem, by the way... I'm wondering how efficient it is compared to the
      ! other solutions offered.

      The Benchmark module can be used to answer questions about relative speed
      efficiency -- but before you do that, please read on...

      In the first place, since we are looking for strings, not patterns
      (at least as I understand the OP), then using a regex will be slower
      than using index() -- your method above would be faster if written
      along the lines of:

      $_ = join(' ', @array);
      if ( index($_,$search) >= 0 ) {
      print "found it\n";
      }

      Now, strictly from a speed point of view, this isn't a bad solution.
      However, from a memory point of view we already have the array in
      memory and now we also have to construct a string of the same data
      in memory (what if the array is large). The method of looping and
      bailing out if we find it is more memory friendly -- it will also be
      quick if the element exists nearer the beginning of the list (and it
      won't be much slower if it is farther along, or doesn't exist in
      the list).

      BUT (and that's a big but), more important than mere efficiency
      concerns (be it speed or memory) is *correctness*. Joining the list
      into a string and then searching for a substring has a very real
      potential for failure. Consider the following example:

      my @array = ('abc' .. 'acd'); # 28 element list: abc abd abe...
      my $search = 'c ab';
      $_ = join(' ',@array);
      if (index($_, $search) >= 0 ) {
      print "Found it\n";
      }

      The above will print "Found it" even though there is no string 'c ab'
      in the list -- because when 'abc' and 'abd' are joined with a space
      we get the string 'abc abd', which does contain the substring 'c ab'.

      Of course, you can try to pick a join-character that you hope won't
      allow this to occur -- but if the array is derived from outside data,
      and the search string is obtained from user input or elsewhere, you
      have a very real potential for unpredictable failure.

      If we just use a simple bail-out loop, we only test real elements of
      the array against the search criteria, using memory that is already
      allocated (plus a little loop overhead), and we only test as many
      elements as necessary:

      foreach my $elem (@array) {
      if ($elem eq $search) {
      print "Found it\n";
      last;
      }
      }

      This way is also easily modified to find out which array element
      is the matching one:

      my $found_it;
      for my $index (0 .. $#array) {
      if($array[$index] eq $search) {
      $found_it = $index;
      last;
      }
      }
      print "Found it at: $found_it\n" if defined $found_it;

      Of course, as with my last post (and the perlfaq4 suggestion) -- if
      such queries are to be made often, storing the data in a hash rather
      than an array is likely the most convenient and efficient solution.

      I hope this helps.

      regards,
      andrew

      --
      Andrew L. Johnson http://members.home.net/andrew-johnson/
      Some people, when confronted with a problem, think 'I know,
      I'll use regular expressions.' Now they have two problems.
      -- Jamie Zawinski, on comp.lang.emacs
    Your message has been successfully submitted and would be delivered to recipients shortly.