Comparing two arrrays I have two arrays:


first one is ip addresses from billing for blocking
second is ip addresses from firewall - already blocked


My task is, compare it, and if ip address new in billing list - block it (run a command) if ip address not in billing list  unblock it.

Current solutions is:

#billing-&gt;router
foreach $ip (@ipfw_ip) {
    if ( grep $_ eq $ip, @bill_ip ) {
    } else {
        `/sbin/ipfw table 11 add $ip`;
        print "$ip blocked\n";
    }
}

#router-&gt;billing
foreach $ip (@bill_ip) {
    if ( grep $_ eq $ip, @ipfw_ip ) {
    } else {
        `/sbin/ipfw table 11 delete $ip`;
        print "$ip unblocked\n";
    }
}


I hate 'grep' in the loops, and looking for better solution. Any advice?

UPD: 
difference function from Set::Functional helps me.

for(difference (\@ipfw_ip, \@bill_ip)) {
     ..._;
}
sub difference(@) {
    my $first = shift;

    return unless $first &amp;&amp; @$first;

    my %set;

    undef @set{@$first};

    do { delete @set{@$_} if @$_ } for @_;

    return keys %set;
}
You can use Set::Functional to make the code very short:

use Set::Functional 'difference';
for(difference [@ipfw_ip], [@bill_ip]) {
    `/sbin/ipfw table 11 add $ip`;
    print "$ip blocked\n";
}


Another advantage of the approach above is that you don't have to worry about duplicate entries in the two arrays.