Arrays 比较两个数组,删除匹配的项
我有两个数组,Arrays 比较两个数组,删除匹配的项,arrays,perl,Arrays,Perl,我有两个数组,@names和@employees,它们用表示姓名的字符串填充@names是二维的,包含对匿名数组的引用,但是我们关心的数据的位置在@names[i][0]。我想循环查看@names,找出哪些姓名不在@employees中 起初我认为向后循环@names,将其与@employees进行比较,并从@names中删除任何匹配项都可以,但我遇到了一些错误。以下是我所拥有的: for my $i (reverse(0 .. $#names)) { foreach my $employe
@names
和@employees
,它们用表示姓名的字符串填充@names
是二维的,包含对匿名数组的引用,但是我们关心的数据的位置在@names[i][0]
。我想循环查看@names
,找出哪些姓名不在@employees
中
起初我认为向后循环@names
,将其与@employees
进行比较,并从@names
中删除任何匹配项都可以,但我遇到了一些错误。以下是我所拥有的:
for my $i (reverse(0 .. $#names)) {
foreach my $employee (@employees) {
if ($names[$i][0] eq $employee) { # line 67
splice(@names, $i, 1);
}
}
}
我遇到了以下错误:
在script.pl第67行第2行的字符串eq中使用未初始化值
这些字符串都是在数组中定义的。所以我猜这是因为我在循环数组时删除了数组中的元素,但是我认为向后循环数组可以防止类似的问题发生
那么,在我的循环中,我错在哪里呢?而且,我一直在为这个循环而挣扎,这向我暗示,我的整个思维过程都出了问题。有更好的方法吗?如果不提供代码,我会返回一个新的@names列表。对于@names中的每个姓名,请检查它是否在@employees中,如果不是,请将其添加到新的姓名列表中。没有理由在此处显式循环。您想要筛选名称:这是一个
grep
。您想检查成员资格:这也可以通过grep
完成
@names = grep {my $name = $$_[0]; not grep $_ eq $name, @employees} @names;
内部阵列的重复扫描不是特别有效;可以通过提前填充集合(实际上是散列)来避免这种情况
my %employees = map +($_ => 1), @employees;
@names = grep !$employees{$$_[0]}, @names;
直接使用值不是更好吗@name=grep$雇员{$},@姓名@DanLittlejohn根据OP的说法,
@names
是一个二维数组,所以$\ucode>仍然是一个列表引用。字符串化它(这是哈希键的情况)没有用处。这会导致在使用“strict refs”时不能将字符串用作数组引用