比较两个数组,删除匹配的项目

时间:2012-06-13 19:08:36

标签: arrays perl

我有两个数组@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中使用未初始化的值。

字符串都在数组中定义。所以我猜这是因为我在循环中删除了数组中的元素,但我认为向后循环数组会阻止这样的问题发生。

那我在循环中哪里出错了?此外,我一直在努力解决这个循环,这暗示着我的整个思考过程出了问题。有没有更好的方法来做到这一点?

2 个答案:

答案 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中,如果没有将其添加到新的名称列表中。