Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Matching 2 unordered arrays then printing the first array highlighting the matches?

by fraizerangus (Sexton)
on Oct 28, 2013 at 18:58 UTC ( [id://1060040]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks

I have 2 arrays, the first has 1882 indexes the second has 1042, both are unordered. All of the second array match the first. I'd like to print the first array and highlight (by printing match) the ones that match and leave the ones that don't unhighlighted, by printing "match" next to if or not? What is the simplest, most direct method which will involve the least number of iterations please.

Much Love DT
  • Comment on Matching 2 unordered arrays then printing the first array highlighting the matches?

Replies are listed 'Best First'.
Re: Matching 2 unordered arrays then printing the first array highlighting the matches?
by hdb (Monsignor) on Oct 28, 2013 at 19:27 UTC

    You create a hash with all elements of array2 as the keys. When iterating through array1, you check whether the elements exists in the hash.

    my %match; undef @match{ @array2 }; for (@array1) { print "$_",exists $match{$_}?" match":"","\n"; }

      Or just use Perl's 'smart' operator (no hash needed):

      print $_ ~~ @array2 ? "$_: Match!\n" : "$_: No Match\n" for @array1;

      Much better...

Re: Matching 2 unordered arrays then printing the first array highlighting the matches?
by Kenosis (Priest) on Oct 28, 2013 at 19:19 UTC

    Consider using the Module List::Compare to obtain the two lists' intersection, then place that intersection into a hash. When you iterate through the first array, check whether there's a key for each element of that array. If there's a key, it's a common element, so 'highlight' it, else leave it 'unhighlighted.'

    Hope this helps!

Re: Matching 2 unordered arrays then printing the first array highlighting the matches?
by Old_Gray_Bear (Bishop) on Oct 28, 2013 at 19:40 UTC
    Dear DT --

    First method (non-Perl):

    1. sort fileA and write it to /tmp
    2. sort fileB and write it to /tmp
    3. Use cmp or diff to detect the differences between the two /tmp files and report.
    Second Method (using Perl):
    1. read fileA and use each value as a hash-key with a hash-value of 1 ($seen_hash{$valueA} = 1;)
    2. read fileB and use each value as a hash-key and add a value of 2 ($seen_hash{$valueB} += 2;)
    3. Read through the hash and report on all keys where the value is '3'.

    ----
    I Go Back to Sleep, Now.

    OGB

      What happens if there are duplicates in fileB?

Re: Matching 2 unordered arrays then printing the first array highlighting the matches?
by thezip (Vicar) on Oct 28, 2013 at 20:23 UTC

    Here's my offering:

    1. Stringify and hashify the smaller array (set the value to '1' for each key)
    2. Iterate through the stringified keys of the larger array, doing an exists() for each value to see if it exists in the smaller array
    3. If it exists, print "Matches'"
    4. If it doesn't, print "Doesn't match"

    What can be asserted without proof can be dismissed without proof. - Christopher Hitchens, 1949-2011
Re: Matching 2 unordered arrays then printing the first array highlighting the matches?
by Laurent_R (Canon) on Oct 28, 2013 at 22:24 UTC

    Frankly, I do not see why using an %already_seen hash would be more complicated than a grep on the content of the smaller file. Actually, when I started to learn Perl about 10 years ago, it took me just a few days to be able to set up a solution with a hash for this type of problem, I learned to use the grep function only a number of months later.

    Using a hash is also algorithmically much more intellectually satisfying. Granted, with about 1,000 records, it does not make much of a difference, and, to tell the truth, I am also sometimes lazy. I just found today a piece of code (not in Perl, in a programming language having no built-in sort function) that I wrote less than a year ago in which I developed a simple 5-line bubble sort, despite its known inefficiencies, just because I knew that my lists to be sorted would usually have an average 2 to 3 elements and never more than 6. Worse than that, in that same language that I mentioned, I am regularly using a goto instruction, because it is in my experience the best way to exit forward of a code block when looping on the records of a database (I am using it exclusively as an equivalent of the next instruction in a Perl loop). I am mentioning these things just to show that I am really not a CS purist or bigot, I also like to keep things simple when there is no point of making them complicated. In the case in point, however, the idea of visiting 1882 times 1042 records when you can do it only once (or twice, depending on what you count) at no cost in terms of code simplicity with a hash really goes against every tenet that I have learned over my past 30 years of programming experience.

      Thirty years ago, the difference might have mattered.
        Thirty differences ago, the years might have mattered.
Re: Matching 2 unordered arrays then printing the first array highlighting the matches?
by Anonymous Monk on Oct 28, 2013 at 21:10 UTC
    Screw all that ... keep it simple. Presumably you are generating a web-page. So, iterate through the first list, and, for each element in the second, use the grep function to look for matching entries to $_. Use a scalar-context since the only thing you care about is whether matching-entries exist. If the result is greater-than-zero, generate the "Match!" string in the second column. Data-volumes in the "thousands of" records frankly do not warrant the use of more-advanced magick.
Re: Matching 2 unordered arrays then printing the first array highlighting the matches?
by gurpreetsingh13 (Scribe) on Oct 29, 2013 at 09:26 UTC
    perl -e 'my @bigArray=1..1883; my @smallArray=1..1043; $_~~@smallArray +?print "Matches=>$_\n":print "$_\n" foreach(@bigArray);'

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (9)
As of 2024-04-16 08:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found