如何找到另一个数组中不存在的一个数组的所有元素?

时间:2015-09-30 13:39:25

标签: arrays regex perl grep

我在研究指向使用grep时发现的答案,特别是因为数组不超过20-40个元素。

我有两个文件名数组@allfiles@keepfiles。我想删除@allfiles中仅存在文件名的文件。 @allfiles的元素多于@keepfiles

我想使用类似的东西:

for(my $ii=0;$ii<=$allfilesSize-1; $ii++)
   {
    # if the current element of @allfiles is not in @keepfiles, delete the file
    unless(grep(@allfiles->[$ii],@keepfiles))
    {
        my $command = "del <value of @allfiles->[$ii]>";
        system($command);
    }
 }

我无法弄清楚如何编写grep语句。 要么我不知道如何正确引用数组元素的值,要么不写正则表达式,或者很可能两者都写。或者有更好的方法吗?

3 个答案:

答案 0 :(得分:4)

您可以使用CPAN上的Array::Utils array_minus来执行此操作。

use strict;
use warnings;
use Array::Utils 'array_minus';
use Data::Printer;

my @allfiles = ('a'..'z');
my @keepfiles = qw(a e i o u);

my @delete_files = array_minus(@allfiles, @keepfiles);

p @delete_files;

<强>输出:

[
    [0]  "b",
    [1]  "c",
    [2]  "d",
    [3]  "f",
    [4]  "g",
    [5]  "h",
    [6]  "j",
    [7]  "k",
    [8]  "l",
    [9]  "m",
    [10] "n",
    [11] "p",
    [12] "q",
    [13] "r",
    [14] "s",
    [15] "t",
    [16] "v",
    [17] "w",
    [18] "x",
    [19] "y",
    [20] "z"
]

或者你可以使用查找哈希,这是Perl中非常常见的习惯用法。首先构建哈希,然后使用exists关键字检查密钥是否存在。

use strict;
use warnings;
use Data::Printer;

my @allfiles = ('a'..'z');
my @keepfiles = qw(a e i o u);

my %lookup = map { $_ => 1 } @keepfiles;
my @delete_files = grep { ! exists $lookup{$_} && $_ } @allfiles;

p @delete_files;

输出与上述相同。

答案 1 :(得分:0)

这样的事情应该有效。只需使用真实数组,并将print语句替换为system命令。

use warnings;
use strict;

my @all = qw(a b c d e f);
my @some = qw(c f);

for my $file (@all){
    if (! grep /^$file\z/, @some){
        print "$file\n";
    }
}

答案 2 :(得分:0)

@simbabque提出的两个变体并不完全相同。 差异是由使用引起的 第二个变体中的<li>表达式中的for(var i = 0; i < lists.length; i += 1) { lists[i].innerHTML = places[i]; }

我理解的

代码&& $_仅用于避免应对0或&#39;&#39; (空字符串)从大数组(@allfiles)到输出数组(@delete_files)。虽然Array :: Utils :: array_minus()没有提供这样的功能。 如果您省略代码my @delete_files = grep { ! exists $lookup{$_} && $_ } @allfiles;,您将收到相同的变体。