In perl how to compare two arrays of objects (comparison logic being coded in a separate subroutine)?
Let me be specific to my problem instead of generalizing it and confusing the audience. In my code I have set of network addresses (members of object-group actually) stored in individual arrays. I would like to compare whether Group A is a subset of Group B.
I am using Net::IP module to parse the IP addresses and use "overlaps" sub-routine to determine if an element (could be individual IP or a subnet) is a superset of another element.
The challenge I am facing is in returning success status only if each element of Group A, belongs to any one element of Group B.
Here is a way I thought of and proceeding to try to code it likewise:
$status = "match";
foreach $ip (@group_a) {
if a_in_b($ip,@group_b) #this sub-routine would be similar but with different comparison function
{
next;
}
else
{
$status = "no match";
last;}
}
Please suggest me if there is a better way to do it, would love to pick up new techniques. The above technique doesn't look sound at all! As I was searching for for some solutions, some references seem to suggest as if I could try using the smart match operator and overload it. But overloading is beyond my level of sophistication in perl, so kindly help!
EDIT: Updated my code as per suggestion. Here is the working version (still need to add bits and pieces for error catching)
use Net::IP;
use strict;
use warnings;
my @subnet = ("10.1.128.0/24","10.1.129.0/24","10.1.130.0/24","10.1.108.4");
my @net = ("10.1.128.0/21","10.1.108.0/22");
sub array_subset {
my ($x, $y) = @_;
a_in_b ($_, @$y) or return '' foreach @$x;
return 1;
};
sub a_in_b {
my $node1 = shift(@_);
my @ip_list = @_;
for my $node2 (@ip_list) {
print $node2, "\n";
my $ip1 = new Net::IP ($node1) || die;
my $ip2 = new Net::IP ($node2) || die;
print "$node1 $node2 \n";
if ($ip1->overlaps($ip2)==$IP_A_IN_B开发者_如何学JAVA_OVERLAP) {
return 1;
}
}
return "";
}
if (array_subset(\@subnet, \@net)) {
print "Matches";
}else
{
print "Doesn't match"
}
Overloading ~~ is a bit of overkill. I would suggest using List::MoreUtils:
use List::MoreUtils qw/all/;
if (all { a_in_b($_, @bignet) } @smallnet) {
# do something
};
Or just rewrite your own code as a sub, and in a more perlish way:
sub array_subset {
my ($x, $y) = @_;
a_in_b ($_, @$y) or return '' foreach @$x;
return 1;
};
# somewhere in the code
if (array_subset(\@subnet, \@net)) {
# do something
};
精彩评论