Каков синтаксис для удаления элемента массива, если вы не знаете его индекс? - PullRequest
0 голосов
/ 02 июня 2018

Вы можете использовать наречие :delete в Perl 6, чтобы удалить элемент массива, если вы знаете его индекс:

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

Кажется, нет другого способа удаления массиваэлементы. эквивалент для Perl 5 delete фактически указывает на это наречие.Вы можете использовать splice, но еще раз вам нужно будет знать индекс.Реализация выглядит так: эта функция, DELETE-POS, которая фактически должна знать индекс массива.

Таким образом, вопрос, как и в заголовке, есть ли способ удаленияэлемент массива (или, в данном случае, ассоциативного массива), если у вас есть дескриптор только самого элемента, а не его индекса?

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Пожалуйста, прочитайте ответ Лизмат для вдумчивого и полезного анализа вашего титульного вопроса, в котором она уделяет должное внимание неоднозначности английского слова «удаление».

Вот один из способов сделать одно из предложений в ееответьте на использование наречия :delete так, чтобы конечный @letters остался таким же массивом с первым элементом :delete 'd, чтобы результат был таким же, как ваш оригинал ([(Any) b c]):

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

Наречие :k на grep говорит о том, что вы хотите, чтобы результатом был индекс.

0 голосов
/ 02 июня 2018

Зависит от того, что вы называете 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]

Но это не похоже на то, что вы намеревались.

...