Відповіді:
Варіант відповіді Шніперсона:
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
якщо ви просто зробите його вільно плаваючим методом і називаєте його як 'foobar'.&remove: (1..2, 4);
(augment може мати проблеми зі складом, якщо використовується кілька разів)
.&remove
це спосіб видалити це.
Моя остання ідея щодо недіяльної роботи (я розповім про реалізацію нижче):
Використання:
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 ]
, тобто, використовуючи знайомі [...]
позначення, але з рядком зліва та додатковим мінусом після відкриття, [
щоб вказати, що вміст підрозділу - це перелік експедицій, а не індекси .
[Редагувати: Я замінив свою оригінальну реалізацію на Бреду. Це, мабуть, неправильно, тому що, як зазначає Бред, його рішення "передбачає, що [експедиції] знаходяться в порядку від найнижчого до найвищого і немає перекриття", і, хоча його не обіцяє інакше, використання [- ... ]
жахливо близьке до роблячи так. Отже, якщо цей синтаксичний цукор мав би хтось використовувати, він, ймовірно, не повинен використовувати рішення Бреда. Можливо, є спосіб усунути припущення Бреда.]
Мені подобається цей синтаксис, але я усвідомлюю, що Ларрі навмисно не створив використання [...]
індексуючих рядків, тому, можливо, мій синтаксис тут є недоцільним для широкого прийняття. Можливо, було б краще, якби були використані різні символи брекетування. Але я думаю, що використання простого синтаксису postcircumfix є приємним.
(Я також намагався реалізувати прямий [ ... ]
варіант для індексації рядків точно так само, як і для Positional
s, але сьогодні не вдалося змусити його працювати з причин, що знаходяться поза мною. Дивно [+ ... ]
працюватимуть, щоб робити exdices, але не робити індекси; це робить для мене немає сенсу! Так чи інакше, я опублікую те, що маю, і вважаю цю відповідь повною.)
[Редагувати: вищезазначене рішення має два аспекти, які слід розглядати як виразні. По-перше, визначений користувачем оператор, синтаксичний цукор, наданий 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 з попередньої відповіді, яку я зв'язав вище, але якщо це швидше, то натомість можна замінити її. * [Редагувати: Очевидно, це замість цього має бути рішення Бреда для варіанту рядка.] *
Усі або перетворюють рядок у список за допомогою, 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
його допомогою створюється якомога менше таких об’єктів.