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

时间:2018-06-02 08:42:17

标签: arrays perl6

如果您知道其索引,可以使用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点到了副词。您可以使用splice,但您必须再次知道索引。实现似乎是this function, DELETE-POS,实际上需要知道数组索引。

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

2 个答案:

答案 0 :(得分:5)

取决于您所谓的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]

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

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]

但这看起来不像你的意图。

答案 1 :(得分:5)

请阅读Lizmat的答案,以便对您的名义问题进行深思熟虑和有益的分析,在该问题中,她会适当注意英语单词的含糊不清,并且删除&#34;

这里有一种方法可以按下她的答案中的一条建议,使用:delete副词,以便最终@letters与第一个元素保持相同的数组{{1因此结果与原始结果(:delete)相同:

[(Any) b c]

my @letters = <a b c>; .[.grep: 'a', :k]:delete given @letters; say @letters; 上的:k副词告诉您希望结果为索引。