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

Hi All,

I'm a newbie and need help in compare one array with a file. I'm expecting a list which is not present on array. The output I'm expecting is server7 and server8, which I'm not getting now.

@a = qw ( server1 server2 server3 server5 ); open FILE , "file"; @b = <FILE>; close FILE; @c = grep!${{map {$_ ,1}@a}}{$_},@b; print "@c";

reading the file.

$cat file server2 server5 server7 server8

Replies are listed 'Best First'.
Re: compare array with file
by trizen (Hermit) on Apr 24, 2012 at 12:27 UTC
    use strict; use warnings; my @c; my @a = qw ( server1 server2 server3 server5 ); my %a = map { $_ => 1 } @a; # Solution 4 my $filename = 'file'; open my $fh, '<:crlf', $filename or die "$0: Can't open $filename $!"; while (defined(my $line = <$fh>)) { chomp $line; # Solution 1 push @c, $line if not $line ~~ \@a; # Solution 2 push @c, $line if not grep { $line eq $_ } @a; # Solution 3 use List::Util qw(first); push @c, $line if not first { $_ eq $line } @a; # Solution 4 push @c, $line if not exists $a{$line}; } close $fh; print "@c";
Re: compare array with file
by BillKSmith (Monsignor) on Apr 24, 2012 at 13:19 UTC
    Consider using the method get_Lonly or get_Ronly from the module List::Compare.
Re: compare array with file
by Anonymous Monk on Apr 24, 2012 at 12:20 UTC

    You forgot to remove trailing whitespace (newlines) chomp or  @a = map { my $l = length $_; unpack "A$l", $_; } <FILE>;

      Thanks to everyone for the help.

Re: compare array with file
by j1n3l0 (Friar) on Apr 24, 2012 at 16:58 UTC
    I'd go with BillKSmith's suggestion:

    use 5.014; use Data::Dump 'pp'; use List::Compare; use Perl6::Slurp; my @a = qw(server1 server2 server3 server5); my @b = slurp \*DATA, {chomp=>1}; my $lc = List::Compare->new(\@a, \@b); pp $lc->get_complement; #=> ("server7", "server8") __END__ server2 server5 server7 server8


    Smoothie, smoothie, hundre prosent naturlig!
Re: compare array with file
by brx (Pilgrim) on Apr 24, 2012 at 13:46 UTC
    Something similar to trizen's solution #4.
    1. make an hash (%seen, %present, %toskip...) from your first array
    2. grep {} the second array
    #!/usr/bin/perl -w use strict; my @blacklist = qw ( server1 server2 server3 server5 ); my %blacklisted = map { $_ => 1 } @blacklist; my @candidate = <DATA>; chomp @candidate; my @servers = grep { not $blacklisted{$_} } @candidate; print "@servers"; __DATA__ server2 server5 server7 server8
Re: compare array with file
by Anonymous Monk on Apr 25, 2012 at 10:43 UTC
    You can use this..
    #! /bin/perl -w use strict; my @a = qw ( server1 server2 server3 server5 ); my @b=(); my @c=(); open(FILE,"file") or die "$!\n"; @b=<FILE>; close FILE; chomp(@b); print "a list is @a\n"; print "b list is @b\n"; foreach my $server (@b) { if( ! grep(/$server/,@a)) { push(@c,$server); } } print "c list is @c\n";
      the output would be:
      a list is server1 server2 server3 server5 b list is server2 server5 server7 server8 c list is server7 server8