Ответы:
Вариант ответа Шниперсона:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
В одной строке:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
или вызывается функцией:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
или с увеличением Str:
use MONKEY-TYPING;
augment class Str {
method remove($a) {
$.comb[(^* ∖ $a.flat).keys.sort].join;
}
};
say '0123456789'.remove: (1..3, 8);
MONKET-TYPING
если вы просто делаете метод free float и вызываете его как 'foobar'.&remove: (1..2, 4);
(augment может иметь проблемы с композицией, если используется несколько раз)
.&remove
это способ удалить это.
Моя последняя идея для операции not-at (я расскажу о реализации ниже):
Применение:
say '0123456789'[- 1..3, 8 ]; # 045679
Реализация, упаковка (вариант) решения Брэда:
multi postcircumfix:<[- ]> (|args) { remove |args }
sub remove( Str:D $str is copy, +@exdices){
for @exdices.reverse {
when Int { $str.substr-rw($_,1) = '' }
when Range { $str.substr-rw($_ ) = '' }
}
$str
}
say '0123456789'[- 1..3, 8 ]; # 045679
Синтаксис для использования оператора, который я объявил, заключается в том string[- list-of-indices-to-be-subtracted ]
, чтобы использовать знакомую [...]
нотацию, но со строкой слева и дополнительным минусом после открытия, [
чтобы указать, что содержимое нижнего индекса представляет собой список, а не индексы .
[Редактировать: я заменил мою оригинальную реализацию на Брэда. Это, вероятно, неправильно, потому что, как отмечает Брэд, его решение «предполагает, что [exdices] находятся в порядке от низшего к высшему, и нет перекрытия», и, хотя он не обещает иначе, использование [- ... ]
очень близко к делать это. Так что, если этот синтаксис сахар должен был использоваться кем-то, он, вероятно, не должен использовать решение Брэда. Возможно, есть способ опровергнуть предположение Брэда.]
Мне нравится этот синтаксис, но я знаю, что Ларри намеренно не использовал [...]
для индексации строки, поэтому мой синтаксис здесь не подходит для широкого применения. Возможно, было бы лучше, если бы использовались некоторые другие символы брекетинга. Но я думаю, что использование простого синтаксиса postcircumfix хорошо.
(Я также попытался реализовать прямой [ ... ]
вариант для индексации строк точно так же, как для Positional
s, но не смог заставить его работать по независящим от меня причинам сегодня вечером. Странно [+ ... ]
будет работать, чтобы добиться успеха, но не сделать индексы; нет никакого смысла для меня вообще! Во всяком случае, я опубликую то, что у меня есть, и считаю этот ответ полным.)
[Редактировать: вышеприведенное решение имеет два аспекта, которые следует рассматривать как отдельные. Сначала пользовательский оператор, синтаксический сахар, предоставляемый postcircumfix:<[- ]> (Str ...
объявлением,. Во-вторых, текст этой декларации. Выше я использовал (вариант) решения Брэда. Мой оригинальный ответ ниже.]
Поскольку ваш вопрос сводится к удалению некоторых индексов [Править: Неправильно, согласно ответу Брэда.].comb
и join
получению результата, ваш вопрос по сути является дубликатом ...
Что такое быстрый способ отменить выбор элементов массива или списка? добавляет еще больше решений для [ .comb ... .join
] ответов здесь.
Реализовано как два мультисимвола, поэтому с Positional
s можно использовать один и тот же синтаксис :
multi postcircumfix:<[- ]> (Str $_, *@exdex) { .comb[- @exdex ].join }
multi postcircumfix:<[- ]> (@pos, *@exdex) { sort keys ^@pos (-) @exdex }
say '0123456789'[- 1..3, 8 ]; # 045679
say (0..9)[- 1..3, 8 ]; # (0 4 5 6 7 9)
sort keys ^@pos (-) @exdices
Реализация лишь немного упрощенная версия @ ответ Себастьяна. Я не сравнивал его с решением jnthn из предыдущего ответа, который я связал выше, но если это быстрее, его можно заменить. * [Edit: Очевидно, что вместо этого должно быть решение Брэда для варианта строки.] *
еще другие варианты:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Каждый или превращает строку в список, используя comb
или используя плоский список индексов.
Нет причин делать что-либо из этого
sub remove( Str:D $str is copy, +@indices ){
for @indices.reverse {
when Int { $str.substr-rw($_,1) = '' }
when Range { $str.substr-rw($_ ) = '' }
}
}
remove("0123456789", 1..3, 8 ); # 045679
remove("0123456789", [1..3, 8]); # 045679
Вышесказанное предполагает, что индексы находятся в порядке от самого низкого до самого высокого, и нет никакого перекрытия.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). Расческа длинна для длинных струн. Спасибо @BradGilbert, это определенно поможет некоторым людям, по крайней мере мне :-)
.comb
его, вам нужно создать множество таких объектов и объединить их вместе. С substr
его помощью создается как можно меньше таких объектов.