开发者

In perl how to compare two arrays of objects (comparison logic being coded in a separate subroutine)?

开发者 https://www.devze.com 2023-03-05 18:04 出处:网络
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 wou

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
};
0

精彩评论

暂无评论...
验证码 换一张
取 消