只是想知道我是否给了两个数组,A和B,如何删除/删除A中也可以在B中找到的那些元素?这样做最有效的方法是什么?
而且,作为一种特殊情况,如果B是后面的结果数组 grep
在A上,怎么做?当然,在这种情况下,我们可以做一个 grep
在否定的条件下。但是在perl中是否存在类似于另一个数组的补充?
谢谢。
只是想知道我是否给了两个数组,A和B,如何删除/删除A中也可以在B中找到的那些元素?这样做最有效的方法是什么?
而且,作为一种特殊情况,如果B是后面的结果数组 grep
在A上,怎么做?当然,在这种情况下,我们可以做一个 grep
在否定的条件下。但是在perl中是否存在类似于另一个数组的补充?
谢谢。
任何时候你在想 found in
你可能正在寻找哈希。在这种情况下,您将创建B值的哈希值。然后你会grep A,检查每个元素的哈希值。
my @A = 1..9;
my @B = (2, 4, 6, 8);
my %B = map {$_ => 1} @B;
say join ' ' => grep {not $B{$_}} @A; # 1 3 5 7 9
正如您所看到的,perl通常不会保持任何形式 found in
表格本身,
所以你必须提供一个。上面的代码可以很容易地包含在一个函数中,但为了提高效率,最好是内联。
看看吧 none
, all
, part
, notall
方法可用 列表:: MoreUtils。您可以使用此模块中提供的方法执行几乎任何设置操作。
有一个很好的教程可用 Perl培训澳大利亚
如果您要求最有效的方式:
my @A = 1..9;
my @B = (2, 4, 6, 8);
my %x;
@x{@B} = ();
my @AminusB = grep !exists $x{$_}, @A;
但你会注意到我和我之间的区别 埃里克斯特罗姆的 解 仅适用于更大的投入。
您可以找到方便的功能方法:
sub complementer {
my %x;
@x{@_} = ();
return sub { grep !exists $x{$_}, @_ };
}
my $c = complementer(2, 4, 6, 8);
print join(',', $c->(@$_)), "\n" for [1..9], [2..10], ...;
# you can use it directly of course
print join(' ', complementer(qw(a c e g))->('a'..'h')), "\n";
你最好使用哈希,但你也可以使用 智能匹配。偷窃行为 埃里克斯特罗姆的例子,
my @A = 1..9;
my @B = (2, 4, 6, 8);
say join ' ' => grep {not $_ ~~ @B } @A; # 1 3 5 7 9
再说一次,你可能最好使用哈希,但你也可以使用 Perl6 ::结。再次偷窃 埃里克斯特罗姆的例子,
use Perl6::Junction qw(none);
my @A = 1..9;
my @B = (2, 4, 6, 8);
say join ' ' => grep {none(@B) == $_} @A; # 1 3 5 7 9
正如已经提到的那样 埃里克斯特罗姆,无论何时你需要搜索特定的东西,如果你有一个哈希,它总是更容易。
Eric有一个更好的解决方案,但可能很难理解。我希望我的内容更容易理解。
# Create a B Hash
my %BHash;
foreach my $element (@B) {
$BHash{$element} = 1;
}
# Go through @A element by element and delete duplicates
my $index = 0;
foreach my $element (@A) {
if (exists $BHash{$element}) {
splice @A, $index, 1; #Deletes $A[$index]
$index = $index + 1;
}
}
在第一个循环中,我们只是创建一个由元素键入的散列 @B
。
在第二个循环中,我们遍历每个元素 @A
,同时跟踪索引 @A
。