замена текста perl6 в массиве

#raku

#raku

Вопрос:

Я пытаюсь применить замену текста ко всему массиву.

Однако, когда я пытаюсь изменить массив, он показывает, что в нем есть только 1 элемент, тогда как в нем должно быть 26.

Приведенный ниже пример в Perl6 REPL:

 > my @a = 'a'..'z'
[a b c d e f g h i j k l m n o p q r s t u v w x y z]
> my @a1 = @a.subst(/<[aeiou]>/, 1, :g)
[1 b c d 1 f g h 1 j k l m n 1 p q r s t 1 v w x y z]
> @a1.elems
1#this should be 26
> @a.elems
26
  

как я могу изменить массив с помощью замены текста по всему массиву и вернуть массив?

также: веб-сайт perl6 не работает, я не могу получить доступ ко многим страницам руководства:(

Комментарии:

1. Пожалуйста, используйте docs.perl6.wakelift.de до тех пор, пока не будут решены проблемы с оборудованием и / или DNS

2. docs.perl6.org теперь он должен снова работать. Если нет, очистите кэш DNS.

3. Некоторые методы предполагают, что их вызывающий элемент является контейнером множественного числа. Если это действительно единственное число, они могут заставить его быть контейнером во множественном числе, содержащим эту единственную вещь. И наоборот, другие методы предполагают, что их вызывающий объект является чем-то особенным. Если это на самом деле множественное число, они могут принудить его к чему-то одному. .subst предположим, что его вызывающий элемент представляет собой одну строку. Если это на самом деле массив, он объединяет элементы массива в одну строку с пробелами между элементами. Отсюда и поведение, которое вы видите.

Ответ №1:

С помощью >>. гипероператора: это вызывает данный метод для каждого элемента списка и создает список результатов вызова.

 my @a = "a".."z";
my @b = @a>>.subst(/ <[aeiou]> /, 1, :g);
dd @a, @b;

# Array @a = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
# Array @b = ["1", "b", "c", "d", "1", "f", "g", "h", "1", "j", "k", "l", "m", "n", "1", "p", "q", "r", "s", "t", "1", "v", "w", "x", "y", "z"]
  

Ответ №2:

.subst это метод Str.

Это означает, что предполагается, что его первый аргумент (вызывающий) является Str. Если это еще не Str, он преобразуется в Str.

Когда вы вызываете .Str массив, он объединяет все значения вместе с пробелом в качестве разделителя.

 my @a = < a b c >;
say @a.perl;       # ["a", "b", "c"]
say @a.Str.perl;   # "a b c"
  

Итак, эти три строки в точности эквивалентны:

 @a.subst(/<[aeiou]>/, 1, :g);
@a.Str.subst(/<[aeiou]>/, 1, :g);
@a.join(" ").subst(/<[aeiou]>/, 1, :g);
  

Perl6 делает это, потому что он согласован. Вы всегда знаете, что результат одного вызова .subst является единственным Str. Вы также знаете, что вызывающий объект обрабатывается как Str.

Если бы он делал что-то другое в массивах, стало бы трудно отслеживать, какие методы меняются в зависимости от вызываемого объекта и как они меняются.

Достаточно взглянуть на Perl5, чтобы увидеть, как сложно запомнить каждую особенность каждой функции, когда они не согласованы.
(Попробуйте подумать обо всех функциях в Perl5, которые работают $_ по умолчанию, и о том, что они делают в скалярном контексте или в контексте списка.)


Вместо вызова .subst для одного значения массива, вы хотите вызвать его для каждого из значений, которые он содержит.

Есть несколько способов сделать это:

 my @ = @a.map( *.subst(…) )

my @ = @a».subst(…)

my @ = do for @a { .subst(…) }

my @ = @a.duckmap( -> Str $_ { .subst(…) } ) # only change Str's
  

Комментарии:

1. Вы рекомендуете назначить анонимный массив @ или обновить @a с помощью .= оператора, как в @a.=map( *.subst(…) ); ? Является ли одно предпочтительным по сравнению с другим? Существуют ли какие-либо обстоятельства, при которых @a.=map( *.subst(…) ); форма завершилась бы неудачей, в то время как @ анонимная форма массива была бы успешной? Спасибо!

2. @jubilatious1 Я бы рекомендовал создавать новые значения по умолчанию, поскольку это, вероятно, создаст проблемы позже. Представьте, что у вас есть функция, которая принимает массив в качестве входных данных и изменяет его на месте. Теперь представьте, что вы вызвали его с массивом, который вы не хотели изменять. И, что еще хуже, вам может потребоваться некоторое время, чтобы даже заметить, что это происходит, не говоря уже о том, чтобы отследить, где и как. (На самом деле я рекомендую вернуть последовательность и позволить вашему вызывающему абоненту решить, хотят ли они сохранить значения по мере их создания.)