Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Comparing 2 arrays but ignoring certain patterns

by hongping (Novice)
on Jun 29, 2012 at 02:09 UTC ( [id://979030]=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to compare 2 array and print the difference at a 3rd file. However how am i going to compare this 2 arrays by ignoring certain patterns: For example: 1st array contains:
ctahci cptcsa0 ctsata:25:seed cptcsa1:50:seed ctsata_1:25:seed
2nd array contains:
cptcsa0 ctsata cptcsa1
I wanna ignore the ":25:seed" and ":50:seed" in the @removelist during comparison. So that the output file will be:
ctahci ctsata_1:25:seed
This is the code for me to find the difference but i got no idea on how to ignore the 2 patterns.
#!/usr/intel/bin/perl @testlist = qw(ctahci,cptcsa0,ctsata:25:seed,cptcsa1:50:seed,ctsata_1: +25:seed) @removelist =qw(cptcsa0,ctsata,cptcsa1) my $outfile = "./new.list"; %removelist=map{$_=>1} @removelist; @newlist=grep(!defined $removelist{$_}, @testlist); # creating new list open (OUTFILE, ">$outfile") or die "Cannot open $outfile for writing \ +n"; ); print OUTFILE "$_\n" foreach (@newlist);;
Any ideas pls help. Thx

Replies are listed 'Best First'.
Re: Comparing 2 arrays but ignoring certain patterns
by AnomalousMonk (Archbishop) on Jun 29, 2012 at 04:40 UTC

    Another case of hash avoidance, and no need for multiple split calls:

    >perl -wMstrict -le "my @testlist = qw( ctahci cptcsa0 ctsata:25:seed cptcsa1:50:seed ctsata_1:25:seed ); my @removelist = qw(cptcsa0 ctsata cptcsa1); ;; my $remove = join ' | ', @removelist; $remove = qr{ $remove }xms; print $remove; ;; my @newlist = grep ! m{ \A $remove \b }xms, @testlist; print qq{'$_'} for @newlist; " (?^msx: cptcsa0 | ctsata | cptcsa1 ) 'ctahci' 'ctsata_1:25:seed'
Re: Comparing 2 arrays but ignoring certain patterns
by NetWallah (Canon) on Jun 29, 2012 at 03:33 UTC
    Fixed a few things:
    #!/usr/intel/bin/perl use strict; use warnings; my @testlist = qw(ctahci cptcsa0 ctsata:25:seed cptcsa1:50:seed ctsata +_1:25:seed); my @removelist =qw(cptcsa0 ctsata cptcsa1); my $outfile = "./new.list"; my %removehash=map{$_=>1} @removelist; my @newlist=grep !defined( $removehash{ (m/(\w+)/)[0] }), @testlist; # creating new list open (my $OUTFILE, ">",$outfile) or die "Cannot open $outfile for writ +ing:$!\n"; print $OUTFILE "$_\n" foreach (@newlist);
    ---Output:---
    ctahci
    ctsata_1:25:seed

    Adjust the regular expression to suite your requirements.

                 I hope life isn't a big joke, because I don't get it.
                       -SNL

      ur script is great, but my @testlist and @removelist may contain more than one word such as:
      ctahci_sip11cs_devslp_deto_exp:50:seed ctahci_sip11cs_devslp_deto_exp2:50:seed
      therefore the code will assume it is same when one word is matching. How to deal with this?
        You will need to test out the conditions you expect to work, and define your problem more clearly.

        I tested the patterns you proposed with my code - it works fine.

        If it does not meet your requirements, as I said in my previous post - feel free to modify the regular expression to work with your requirements.

                     I hope life isn't a big joke, because I don't get it.
                           -SNL

        I don't understand, especially where you say

        ... @removelist may contain more than one word such as:
        ctahci_sip11cs_devslp_deto_exp:50:seed
        ctahci_sip11cs_devslp_deto_exp2:50:seed

        The string  'ctahci_sip11cs_devslp_deto_exp:50:seed' doesn't look like anything appearing in the  @removelist array in your OPed example code. Can you give an example of data for which NetWallah's code fails?

      After the several tries. This code just perfect for me. Thanks a lot. =)
Re: Comparing 2 arrays but ignoring certain patterns
by Kenosis (Priest) on Jun 29, 2012 at 03:46 UTC

    Omit building the hash and try the following grep that uses smart matching:

    @newlist = grep !((split /:/)[0] ~~ @removelist), @testlist;

    Output:

    ctahci ctsata_1:25:seed

    Update:

    NetWallah provided excellent fixes for your code, and it generates your desired output. You may still, however, use the above grep that doesn't use a hash.

      this is no working. syntax error at "]~"
        The smart match operator ( ~~ ) was introduced in perl-5.10, so you'll need perl newer than 5.10 if you want to try it
Re: Comparing 2 arrays but ignoring certain patterns
by muba (Priest) on Jun 29, 2012 at 02:26 UTC
    @testlist = map { s/:.+//; $_ } @testlist;   # Strip everything from the column onward
      but i want to have the :25:seed and :50:seed in my outputlist.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-25 20:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found