我有两个数组@names
和@employees
,它们填充了代表名称的字符串。 @names
是2维,包含对匿名数组的引用,但我们关注的数据的位置是@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中使用未初始化的值。
字符串都在数组中定义。所以我猜这是因为我在循环中删除了数组中的元素,但我认为向后循环数组会阻止这样的问题发生。
那我在循环中哪里出错了?此外,我一直在努力解决这个循环,这暗示着我的整个思考过程出了问题。有没有更好的方法来做到这一点?
答案 0 :(得分:10)
没有理由在这里明确循环。您想要过滤名称:这是grep
。您想检查成员资格:也可以由grep
完成。
@names = grep {my $name = $$_[0]; not grep $_ eq $name, @employees} @names;
内部阵列的重复扫描不是特别有效;可以通过提前预先填充一个集合(实际上是哈希)来避免它。
my %employees = map +($_ => 1), @employees;
@names = grep !$employees{$$_[0]}, @names;
答案 1 :(得分:0)
在不提供代码的情况下,我要做的是返回一个新的@names列表。对于@names中的每个名称,检查它是否在@employees中,如果没有将其添加到新的名称列表中。