如果不知道索引,删除数组元素的语法是什么?

What is the syntax for deleting an array element if you don't know its index?

如果知道索引,可以使用 Perl 6 中的 adverb :delete 删除数组元素:

my @letters = <a b c>; @letters[0]:delete; say @letters
# OUTPUT: «[(Any) b c]␤»

但是,如果您不知道索引,则无法执行此操作:

my @letters = <a b c>; $_:delete if $elem eq 'a' for @letters
#ERROR! → Variable '$_:delete' is not declared

如果声明循环变量is rw还是同样的问题:

my @letters = <a b c>; for @letters -> $l is rw { $l:delete if $l eq 'a' }; say @letters
#ERROR! → Variable '$l:delete' is not declared

似乎没有其他删除数组元素的方法。 equivalent for Perl 5's delete points, in fact, to that adverb. You could use splice but once again you would have to know the index. The implementation seems to be this function, DELETE-POS,实际上需要知道数组索引。

所以问题是,如标题所示,如果您只有元素本身的句柄,而不是其索引,是否有删除数组(或就此而言,关联数组)元素的方法?

取决于你叫什么delete。在内部,在数组上,执行 DELETE-POS 将数组中的元素绑定到 nqp::null,这将丢弃位于该位置的任何容器。在 HLL 级别,这由数组的类型表示:

my Str @letters = <a b c>;
@letters[1]:delete;
say @letters;   # [a (Str) c]

但是你可以通过分配 Nil:

来达到同样的效果
my Str @letters = <a b c>;
@letters[1] = Nil;
say @letters;   # [a (Str) c]

在这种情况下,该元素的容器保持不变,您只需让它恢复到 "natural" 状态。如果您对这种类型的删除感到满意,您也可以在循环中使用它:

my Str @letters = <a b c>;
$_ = Nil if $_ eq "b" for @letters;
say @letters;   # [a (Str) c]

当我说:恢复到它的自然状态时,这也包括任何默认值:

my Str @letters is default<foo> = <a b c>;
$_ = Nil if $_ eq "b" for @letters;
say @letters;   # [a foo c]

如果你想真正从列表中删除元素而不保留现有元素,你当然可以使用grep:

my @letters = <a b c>;
@letters .= grep: * ne "b";
say @letters;  # [a c]

但这似乎不是您想要的。

请阅读 Lizmat 的回答,以获得对您的标题问题的深思熟虑和有益的分析,她在其中适当注意英语单词的歧义 "deleting"。

这里有一种方法可以将她的回答中的一个建议改回使用 :delete 副词,以便最终的 @letters 与第一个元素 :delete 保持相同的数组这样结果就和原来的一样了 ([(Any) b c]):

my @letters = <a b c>;
.[.grep: 'a', :k]:delete given @letters;
say @letters;

grep 上的 :k 副词告诉它您希望结果作为索引。