如何将散列中可变数量的数组传递给List::Compare perl模块?

如何将散列中可变数量的数组传递给List::Compare perl模块?,perl,list,hash,compare,Perl,List,Hash,Compare,我知道这个问题以前在这里被问过()。据我所知,没有人回答。如果您回答,请包括一个使用List::Compare->new()构造函数的示例 能够接受多个数组作为输入。但是,如果您事先不知道将有多少传递给构造函数,则没有示例说明如何执行此操作 手册页中的示例: $lcm = List::Compare->new(\@Al, \@Bob, \@Carmen, \@Don, \@Ed); 或者 您可以使用“single hashref”构造函数格式来构建 列表::比较对象以同时处理三个或多个列

我知道这个问题以前在这里被问过()。据我所知,没有人回答。如果您回答,请包括一个使用List::Compare->new()构造函数的示例

能够接受多个数组作为输入。但是,如果您事先不知道将有多少传递给构造函数,则没有示例说明如何执行此操作

手册页中的示例:

$lcm = List::Compare->new(\@Al, \@Bob, \@Carmen, \@Don, \@Ed);
或者

您可以使用“single hashref”构造函数格式来构建 列表::比较对象以同时处理三个或多个列表:

$lcm=List::Compare->new({lists=>[\@Al,\@Bob,\@Carmen,\@Don,@Ed],})

我需要使用上面的“SingleHashRef”构造函数,因为我不知道有多少列表(数组)将传递给构造函数。我最接近的是:

my %l;
my @a = ("fred", "barney", "pebbles", "bambam", "dino");
my @b = ("george", "jane", "elroy", "judy");
my @c = ("homer", "bart", "marge", "maggie");
my @d = ("fred", "barney", "pebbles", "bambam", "dino");
my @e = ("fred", "george", "jane", "elroy", "judy", "pebbles");

$l{'lists'}{'a'} = [ @a ];
$l{'lists'}{'b'} = [ @b ];
$l{'lists'}{'c'} = [ @c ];
$l{'lists'}{'d'} = [ @d ];
$l{'lists'}{'e'} = [ @e ];

my $lc = List::Compare->new(\%l);
my @intersection = $lc->get_intersection;
print @intersection . "\n";
我得到:

需要正确定义“列表”键:at/usr/local/share/perl5/List/Compare.pm第21行

Compare.pm代码(第21行)为:

有人能告诉我如何从简单数组构造和命名这个散列吗?我需要能够不断地处理各种各样的问题。可能涉及数百个阵列


更新

@博罗丁的回答正是我所需要的。我为糟糕的数据道歉,我正试图想出一些简洁的东西。下面是从该代码派生的内容

my @sets_to_process = qw( DOW SP500 has_trend_lines_day );
my @sets;
my $num_sets = $#sets_to_process;

for my $i (0 .. $num_sets) {
    my @set = get_ids_in_list( $dbh, $sets_to_process[$i] );
    push @sets, \@set;
}

my $lc = List::Compare->new(@sets);
my @intersection = $lc->get_intersection;

print "Sets:\n";
printf "  %s\n", join ', ', @$_ for @sets;
print "\n";

print "Intersection:\n";
printf "  %s\n", @intersection? join(', ', @intersection) : 'None';
print "\n";

参数构造的问题在于,您将
%l
(顺便说一下,这是一个可怕的标识符)定义为包含数组哈希的哈希,如下所示

(
  lists => {
    a => ["fred", "barney", "pebbles", "bambam", "dino"],
    b => ["george", "jane", "elroy", "judy"],
    c => ["homer", "bart", "marge", "maggie"],
    d => ["fred", "barney", "pebbles", "bambam", "dino"],
    e => ["fred", "george", "jane", "elroy", "judy", "pebbles"],
  },
)
for my $i ( 0 .. $num_sets-1 ) { ... }
my @sets = map [ get_ids_in_list($dbh, $_) ], @sets_to_process;
但是文档很清楚,它应该是一个包含数组数组的简单散列

(
  lists => [
    ["fred", "barney", "pebbles", "bambam", "dino"],
    ["george", "jane", "elroy", "judy"],
    ["homer", "bart", "marge", "maggie"],
    ["fred", "barney", "pebbles", "bambam", "dino"],
    ["fred", "george", "jane", "elroy", "judy", "pebbles"],
  ],
)
此外,“您不知道有多少列表(数组)将传递给构造函数”,这对您的问题没有帮助,因为您所做的只是将问题推送到数据结构中,而不是将其保持在参数级别

由于交集是一个空集,因此很难帮助您处理您提供的数据,因此这里有一个示例程序,您可以使用它生成五到十组16个随机字母。它每次运行时都会创建不同的数据,并将数组引用列表作为参数直接传递给
new
构造函数,而不是使用对单个
列表
元素的哈希的引用

use strict;
use warnings;

use List::Util 'shuffle';
use List::Compare;

my @sets;

my $num_sets = 5 + rand(6);

for (1 .. $num_sets) {
  my @set = (shuffle 'A' .. 'Z')[0..16];
  push @sets, [ sort @set ];
}

my $lc = List::Compare->new(@sets);
my @overlap = $lc->get_intersection;

print "Sets:\n";
printf "  %s\n", join ', ', @$_ for @sets;
print "\n";

print "Intersection:\n";
printf "  %s\n", @overlap ? join(', ', @overlap) : 'None';
print "\n";
样本输出

Sets:
  B, C, D, E, F, G, K, L, M, O, P, Q, S, U, V, W, X
  B, C, D, F, G, I, J, L, M, P, R, T, U, V, W, X, Y
  A, B, C, D, F, G, H, K, L, M, O, R, T, U, V, W, Y
  A, B, D, G, H, I, K, L, M, O, R, T, U, V, W, Y, Z
  A, B, C, D, E, F, H, J, K, L, M, P, Q, S, U, V, Z

Intersection:
  B, D, L, M, U, V

更新

关于您问题中的更新代码,您的标识符
$num_sets
命名错误,因为它是
@sets
中最后一个元素的索引,或者比实际的集合数少一个

如果你想使用一个变量,那么你应该说

my $num_sets = @sets_to_process;
然后像这样循环

(
  lists => {
    a => ["fred", "barney", "pebbles", "bambam", "dino"],
    b => ["george", "jane", "elroy", "judy"],
    c => ["homer", "bart", "marge", "maggie"],
    d => ["fred", "barney", "pebbles", "bambam", "dino"],
    e => ["fred", "george", "jane", "elroy", "judy", "pebbles"],
  },
)
for my $i ( 0 .. $num_sets-1 ) { ... }
my @sets = map [ get_ids_in_list($dbh, $_) ], @sets_to_process;
但是在这种情况下,您根本不需要索引,最好忘记
$num_set
,只写这个

for my $set ( @sets_to_process ) {
    my @set = get_ids_in_list($dbh, $set);
    push @sets, \@set;
}
甚至可以像这样使用
map

(
  lists => {
    a => ["fred", "barney", "pebbles", "bambam", "dino"],
    b => ["george", "jane", "elroy", "judy"],
    c => ["homer", "bart", "marge", "maggie"],
    d => ["fred", "barney", "pebbles", "bambam", "dino"],
    e => ["fred", "george", "jane", "elroy", "judy", "pebbles"],
  },
)
for my $i ( 0 .. $num_sets-1 ) { ... }
my @sets = map [ get_ids_in_list($dbh, $_) ], @sets_to_process;

在编写程序时,您可能不知道有多少个列表,但程序知道在调用点有多少个列表,对吗?我很高兴您的问题得到了解决,但您不应该为了这么说而发布其他解决方案。你不必说什么,但如果你说了,那就应该是对答案的一个评论。最终,无论出于何种原因,你都可以对你认为好(或无用)的解决方案投赞成票(或反对票)。如果你的问题已经解决,那么你应该通过点击绿色的勾号来接受最适合你的解决方案,这样其他人就可以看到这个问题不需要进一步的输入。欢迎来到堆栈溢出