Câu trả lời:
Biến thể của Shnipersons trả lời:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
Trong một dòng:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
hoặc được gọi bởi một chức năng:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
hoặc với sự gia tăng của Str:
use MONKEY-TYPING;
augment class Str {
method remove($a) {
$.comb[(^* ∖ $a.flat).keys.sort].join;
}
};
say '0123456789'.remove: (1..3, 8);
MONKET-TYPING
nếu bạn chỉ làm cho nó trở thành phương thức nổi miễn phí và gọi nó là 'foobar'.&remove: (1..2, 4);
(gia tăng có thể có vấn đề với thành phần nếu được sử dụng nhiều lần)
.&remove
là một cách để loại bỏ điều đó.
Ý tưởng mới nhất của tôi cho một hoạt động không hoạt động (Tôi sẽ đề cập đến việc thực hiện bên dưới):
Sử dụng:
say '0123456789'[- 1..3, 8 ]; # 045679
Thực hiện, gói (một biến thể) giải pháp của Brad:
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
Cú pháp sử dụng toán tử mà tôi đã khai báo là string[- list-of-indices-to-be-subtracted ]
, bằng cách sử dụng [...]
ký hiệu quen thuộc , nhưng với một chuỗi ở bên trái và một dấu trừ bổ sung sau khi mở [
để chỉ ra rằng nội dung đăng ký là một danh sách các ngoại lệ thay vì chỉ mục .
[Chỉnh sửa: Tôi đã thay thế triển khai ban đầu của mình bằng Brad's. Điều đó có lẽ đã sai lầm bởi vì, như Brad lưu ý, giải pháp của anh ta "giả định rằng [exdices] theo thứ tự từ thấp nhất đến cao nhất, và không có sự chồng chéo.", Và trong khi anh ta không hứa hẹn gì khác, thì việc sử dụng [- ... ]
rất gần với làm như vậy. Vì vậy, nếu đường cú pháp này được sử dụng bởi ai đó, có lẽ họ không nên sử dụng giải pháp của Brad. Có lẽ có một cách để loại bỏ giả định mà Brad đưa ra.]
Tôi thích cú pháp này nhưng tôi biết rằng Larry đã cố tình không xây dựng để sử dụng các [...]
chuỗi chỉ mục nên có lẽ cú pháp của tôi ở đây không phù hợp để áp dụng rộng rãi. Có lẽ sẽ tốt hơn nếu một số ký tự dấu ngoặc khác nhau được sử dụng. Nhưng tôi nghĩ rằng việc sử dụng một cú pháp postcircumfix đơn giản là tốt.
(Tôi cũng đã cố gắng thực hiện một [ ... ]
biến thể thẳng để lập chỉ mục các chuỗi theo cách chính xác giống như đối với Positional
s nhưng đã không làm cho nó hoạt động vì lý do ngoài tôi tối nay. Thật kỳ lạ [+ ... ]
sẽ làm việc hết sức nhưng không làm chỉ số; Không có ý nghĩa gì với tôi cả! Dù sao đi nữa, tôi sẽ đăng những gì tôi có và xem xét câu trả lời này hoàn chỉnh.)
[Chỉnh sửa: Giải pháp trên có hai khía cạnh nên được xem là khác biệt. Đầu tiên, một toán tử do người dùng định nghĩa, đường cú pháp được cung cấp bởi postcircumfix:<[- ]> (Str ...
khai báo. Thứ hai, cơ thể của tuyên bố đó. Ở trên tôi đã sử dụng (một biến thể) giải pháp của Brad. Câu trả lời ban đầu của tôi là dưới đây.]
Vì câu hỏi của bạn tập trung vào việc loại bỏ một số chỉ số của a [Chỉnh sửa: Sai, theo câu trả lời của Brad.].comb
và gửi lại join
kết quả, nên câu hỏi của bạn về cơ bản là một bản sao của ...
Một cách nhanh chóng để bỏ chọn các thành phần mảng hoặc danh sách là gì? thêm nhiều giải pháp cho .comb ... .join
câu trả lời [ ] ở đây.
Được triển khai dưới dạng nhiều multis nên có thể sử dụng cùng một cú pháp với 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)
Việc sort keys ^@pos (-) @exdices
triển khai chỉ là một phiên bản hơi đơn giản của câu trả lời của @ Sebastian. Tôi chưa đánh giá nó so với giải pháp của jnthn từ câu trả lời trước đó tôi đã liên kết ở trên nhưng nếu nhanh hơn thì nó có thể được hoán đổi thay thế. * [Chỉnh sửa: Rõ ràng thay vào đó nên là giải pháp của Brad cho biến thể chuỗi.] *
một biến thể khác:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Mọi người đều biến chuỗi thành một danh sách bằng cách sử dụng comb
hoặc sử dụng danh sách phẳng các chỉ mục.
Không có lý do để làm một trong những điều đó
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
Các giả định ở trên cho rằng các chỉ số theo thứ tự từ thấp nhất đến cao nhất và không có sự trùng lặp.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). Comb rất dài cho chuỗi dài Cảm ơn @BradGilbert, điều này chắc chắn sẽ giúp một số người, ít nhất là tôi :-)
.comb
nó phải tạo ra nhiều đối tượng đó và kết hợp chúng lại với nhau. Với substr
nó tạo ra càng ít các đối tượng đó càng tốt.