akm2 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to search thru 2 arrays for the same string. Record the matching indexes of both search in the same array of results. Then weed out the duplicate results & process the results. Here is the code I've been trying to use.

&readbksic(); &readbkprm(); $pss = "$in{'productsearch'}"; &productsearchbymodel($pss); &productsearchbydesc($pss); @matchlist = (@modelmatches,@descmatches); my @matches = keys %{ { map {$_=>1 } @matchlist} }; &DisplayHTML('/usr/local/apache/post/invorder.pl/screens/display_produ +cts_top.html'); foreach $linenumber (@matches){ $VCD = $BKSIC_MFG[$linenumber]; $VMN = $BKSIC_MODEL[$linenumber]; $VPD = $BKSIC_DESC[$linenumber]; $QOH = $BKSIC_QOH[$linenumber]; &DisplayHTMLOnly('/usr/local/apache/post/invorder.pl/screens/displ +ay_products_middle.html'); } &DisplayHTMLOnly('/usr/local/apache/post/invorder.pl/screens/displ +ay_products_bottom.html'); exit; } } sub productsearchbymodel { my $modelterms = shift; my $modelpattern = join "|", split " ", $modelterms; my $modelcase = $in{'case'} eq 'insensitive'?"(?i)":""; $modelpattern = qr/$modelcase$modelpattern/; # my @modelmatches = grep { /$modelpattern/ } @BKSIC_MODEL; #This w +ill store the actual matching string my @modelmatches = grep { $BKSIC_MODEL[$_] =~ /$modelpattern/ } 0. +.$#BKSIC_MODEL; #This will store the index ID of the matching array e +lement. return @modelmatches; } sub productsearchbydesc { my $descterms = shift; my $descpattern = join "|", split " ", $descterms; my $desccase = $in{'case'} eq 'insensitive'?"(?i)":""; $descpattern = qr/$case$pattern/; # my @descmatches = grep { /$descpattern/ } @BKSIC_DESC; #This will + store the actual matching string my @descmatches = grep { $BKSIC_DESC[$_] =~ /$descpattern/ } 0..$# +BKSIC_DESC; #This will store the index ID of the matching array eleme +nt. return @descmatches; }

When I perform only 1 search the code works fine. When I try to perform both, no matches are found.

Replies are listed 'Best First'.
Re: Conflicts combining arrays?
by merlyn (Sage) on Mar 22, 2001 at 21:14 UTC
    As a general rule of thumb, the word "search" near the word "array" generally screams "wrong technology" at me.
    • Arrays are for ordering
    • Hashes are for searching
    Recast your problem using hashes, and I think you'll get closer.

    -- Randal L. Schwartz, Perl hacker

Re: Conflicts combining arrays?
by arturo (Vicar) on Mar 22, 2001 at 21:28 UTC

    The most serious problem with this code is the improper use of return in your subroutines. You aren't capturing the values your subroutines return. For example, if I want to get the return value of

    sub double_each { return map {$_ * 2 } @_; }

    I have to call it like this: @list_of_nums = double_each(@list_of_nums); (assuming, of course, I have numbers in @list_of_nums before I make the call. Currently, your calls to your search subs are simply throwing away the return values.

    You're not using use strict here or running under -w (or with use warnings should you be using perl 5.6.0) as far as I can tell. If so, you would have been warned about using those arrays in "void context" (which is how Perl tells you you're throwing away the return values) But let's start with the biggest single thing: change those two lines before you create @matchlist and try the following:

    my @descmatches = productsearchbydesc($pss); my @modelmatches = productsearchbymodel($pss);

    That will get you part of the way.

    Further advice: you've got two different subroutines that differ only in the array they search (otherwise the code is entirely interchangeable). Use that fact! Write ONE subroutine, and have it accept as arguments the search string AND a reference to the array that is to be searched:

    sub searcharray { my ($terms, @array) = @_; ... my @matches = grep { $array[$_] =~ /$pattern/ } 0 .. $#array; @matches; } # call this with my @matches = searcharray($pss, @BKSIC_DESC);

    Final note: it's much more efficient to pass around references to arrays and hashes than it is to pass around arrays and hashes. Read perlreftut for how to use references.

    HTH.

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Re: Conflicts combining arrays?
by dvergin (Monsignor) on Mar 22, 2001 at 21:18 UTC
    First and most important: use strict;. It is your good, good friend.

    It would tell you, for instance that you have not set @modelmatches and @descmatches based on the return results from your two search routines as you probably intended.