В Perl, как сравнить два массива объектов (логика сравнения кодируется в отдельной подпрограмме)? - PullRequest
0 голосов
/ 14 мая 2011

Позвольте мне быть конкретным с моей проблемой, а не обобщать ее и вводить в заблуждение аудиторию. В моем коде у меня есть набор сетевых адресов (фактически, членов объектной группы), хранящихся в отдельных массивах. Я хотел бы сравнить, является ли группа A подмножеством группы B.

Я использую модуль Net :: IP для анализа IP-адресов и использую подпрограмму «перекрытия», чтобы определить, является ли элемент (может быть отдельным IP или подсетью) надмножеством другого элемента.

Проблема, с которой я сталкиваюсь, заключается в возвращении статуса успеха, только если каждый элемент группы A принадлежит какому-либо одному элементу группы B.

Вот способ, которым я подумал и пытаюсь аналогичным образом его кодировать:

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

Пожалуйста, предложите мне, если есть лучший способ сделать это, хотел бы выбрать новые методы. Вышеупомянутая техника не выглядит звучащей на всех! Когда я искал некоторые решения, некоторые ссылки , похоже, наводят на мысль, что я мог бы попытаться использовать оператор интеллектуального сопоставления и перегрузить его. Но перегрузка выше моего уровня сложности в Perl, так что помогите!

EDIT: Обновил мой код согласно предложению. Вот рабочая версия (все еще нужно добавить биты и кусочки для отлова ошибок)

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_OVERLAP) {
      return 1;
    }

  }
  return "";
}

if (array_subset(\@subnet, \@net)) {
  print "Matches";
}else
{
  print "Doesn't match"
}

1 Ответ

2 голосов
/ 15 мая 2011

Перегрузка ~~ - это немного излишне. Я бы предложил использовать List :: MoreUtils :

use List::MoreUtils qw/all/;
if (all { a_in_b($_, @bignet) } @smallnet) {
     # do something
};

Или просто переписать свой собственный код как подпрограмму, и более изящно:

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
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...