我在研究指向使用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
语句。
要么我不知道如何正确引用数组元素的值,要么不写正则表达式,或者很可能两者都写。或者有更好的方法吗?
答案 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;
,您将收到相同的变体。