Jawaban:
Varian jawaban Shnipersons:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
Dalam satu baris:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
atau disebut dengan fungsi:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
atau dengan augmentasi Str:
use MONKEY-TYPING;
augment class Str {
method remove($a) {
$.comb[(^* ∖ $a.flat).keys.sort].join;
}
};
say '0123456789'.remove: (1..3, 8);
MONKET-TYPING
jika Anda hanya membuatnya metode mengambang bebas dan menyebutnya sebagai 'foobar'.&remove: (1..2, 4);
(augment dapat memiliki masalah dengan komposisi jika digunakan beberapa kali)
.&remove
cara untuk menghapusnya.
Gagasan terbaru saya untuk tidak-beroperasi (saya akan membahas implementasi di bawah):
Pemakaian:
say '0123456789'[- 1..3, 8 ]; # 045679
Implementasi, pembungkus (varian) solusi 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
Sintaks untuk menggunakan operator yang telah saya nyatakan adalah string[- list-of-indices-to-be-subtracted ]
, yaitu menggunakan [...]
notasi yang umum , tetapi dengan string di sebelah kiri dan minus tambahan setelah pembukaan [
untuk menunjukkan bahwa konten subskrip adalah daftar exdices daripada indeks .
[Sunting: Saya telah mengganti implementasi asli saya dengan Brad. Itu mungkin salah arah karena, seperti yang dicatat Brad, solusinya "mengasumsikan bahwa [pengeluaran] dalam urutan dari terendah ke tertinggi, dan tidak ada tumpang tindih.", Dan sementara itu tidak menjanjikan sebaliknya, menggunakan [- ... ]
sangat dekat dengan melakukannya. Jadi jika gula sintaks ini digunakan oleh seseorang, mereka mungkin tidak boleh menggunakan solusi Brad. Mungkin ada cara untuk menghilangkan anggapan yang dibuat Brad.]
Saya suka sintaks ini tetapi saya sadar bahwa Larry sengaja tidak membangun [...]
untuk mengindeks string jadi mungkin sintaks saya di sini tidak pantas untuk adopsi luas. Mungkin akan lebih baik jika beberapa karakter tanda kurung yang berbeda digunakan. Tapi saya pikir penggunaan sintaks postcircumfix sederhana itu bagus.
(Saya juga mencoba menerapkan [ ... ]
varian langsung untuk string pengindeksan dengan cara yang persis sama seperti untuk Positional
s tetapi gagal membuatnya berfungsi karena alasan di luar saya malam ini. Aneh [+ ... ]
akan bekerja untuk melakukan exdices tetapi tidak untuk melakukan indeks; yang membuat sama sekali tidak masuk akal bagi saya! Bagaimanapun, saya akan memposting apa yang saya miliki dan menganggap jawaban ini lengkap.)
[Sunting: Solusi di atas memiliki dua aspek yang harus dilihat sebagai berbeda. Pertama, operator yang ditentukan pengguna, gula sintaksis yang disediakan oleh postcircumfix:<[- ]> (Str ...
deklarasi. Kedua, badan deklarasi itu. Di atas saya telah menggunakan (varian) solusi Brad. Jawaban asli saya di bawah.]
Karena pertanyaan Anda bermuara pada menghapus beberapa indeks dari [Sunting: Salah, sesuai jawaban Brad.].comb
, dan mengembalikan join
hasilnya, pertanyaan Anda pada dasarnya adalah duplikat dari ...
Apa cara cepat untuk menghilangkan elemen array atau daftar? menambahkan lebih banyak solusi untuk .comb ... .join
jawaban [ ] di sini.
Diimplementasikan sebagai dua multis sehingga sintaks yang sama dapat digunakan dengan 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)
The sort keys ^@pos (-) @exdices
implementasi adalah hanya sedikit versi sederhana dari @ jawaban Sebastian. Saya belum membandingkannya dengan solusi jnthn dari jawaban sebelumnya yang saya tautkan di atas, tetapi jika itu lebih cepat maka dapat ditukar sebagai gantinya. * [Sunting: Jelas itu seharusnya menjadi solusi Brad untuk varian string.] *
varian lain:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Setiap orang mengubah string menjadi daftar menggunakan comb
atau menggunakan daftar indeks datar.
Tidak ada alasan untuk melakukan hal-hal itu
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
Di atas mengasumsikan bahwa indeks berada dalam urutan dari terendah ke tertinggi, dan tidak ada tumpang tindih.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). Sisir panjang untuk string panjang Terima kasih @BradGilbert, ini pasti akan membantu beberapa orang, setidaknya saya :-)
.comb
harus membuat banyak objek tersebut, dan menggabungkannya kembali. Dengan substr
itu menciptakan objek-objek tersebut sesedikit mungkin.