คำถามที่พบบ่อย: ใน Raku คุณจะลบอักขระบางตัวออกจากสตริงตามดัชนีของพวกเขาได้อย่างไร
ว่าฉันต้องการลบดัชนี 1 ถึง 3 และ 8
xxx("0123456789", (1..3, 8).flat); # 045679
คำถามที่พบบ่อย: ใน Raku คุณจะลบอักขระบางตัวออกจากสตริงตามดัชนีของพวกเขาได้อย่างไร
ว่าฉันต้องการลบดัชนี 1 ถึง 3 และ 8
xxx("0123456789", (1..3, 8).flat); # 045679
คำตอบ:
ตัวแปรของ Shnipersons ตอบ:
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วิธีการลบนั้น
.value.print if .key !(elem) (1,2,3,8) for '0123456789'.comb.pairs
แนวคิดล่าสุดของฉันสำหรับการดำเนินการที่ไม่ใช่ (ฉันจะกล่าวถึงการติดตั้งด้านล่าง):
การใช้งาน:
say '0123456789'[- 1..3, 8 ]; # 045679
การนำไปใช้งานการห่อ (ตัวแปร) โซลูชันของ 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
ไวยากรณ์ที่จะใช้ประกอบการที่ฉันได้ประกาศเป็นstring[- list-of-indices-to-be-subtracted ]เช่นใช้คุ้นเคย[...]สัญกรณ์ แต่ด้วยเชือกด้านซ้ายและลบเพิ่มเติมหลังจากการเปิด[เพื่อบ่งชี้ว่าเนื้อหาห้อยเป็นรายการexdicesมากกว่าดัชนี
[แก้ไข: ฉันได้แทนที่การใช้งานดั้งเดิมของฉันกับแบรด ที่อาจผิดหัวเพราะเป็นบันทึกแบรดแก้ปัญหาของเขา "สันนิษฐานว่า [exdices] อยู่ในลำดับจากต่ำสุดไปสูงสุดและไม่มีการทับซ้อน." และในขณะที่เขาไม่ได้สัญญาว่าจะเป็นอย่างอื่นโดยใช้[- ... ]เป็นชะมัดใกล้กับ ทำเช่นนั้น ดังนั้นหากมีคนใช้น้ำตาลซินแท็กซ์นี้พวกเขาไม่ควรใช้สารละลายของแบรด บางทีอาจมีวิธีกำจัดข้อสันนิษฐานของแบรดที่ทำให้]
ฉันชอบไวยากรณ์นี้ แต่ทราบว่า Larry จงใจไม่ได้สร้างการใช้งานของ[...]สายดัชนีดังนั้นบางทีไวยากรณ์ของฉันที่นี่ไม่เหมาะสมสำหรับการยอมรับอย่างกว้างขวาง อาจจะดีกว่าถ้าใช้ตัวอักษรคร่อมที่แตกต่างกัน แต่ฉันคิดว่าการใช้ไวยากรณ์ postcircumfix ง่าย ๆ ดี
(ฉันยังได้ลองใช้ชุด[ ... ]ตัวแปรแบบตรงสำหรับสตริงการจัดทำดัชนีในลักษณะเดียวกับสำหรับPositionals แต่ล้มเหลวในการทำให้มันทำงานด้วยเหตุผลที่เกินกว่าฉันในคืนนี้แปลก ๆ[+ ... ]จะทำงานเพื่อทำ exdices แต่ไม่ต้องทำดัชนี; ไม่มีเหตุผลสำหรับฉันเลย! ฉันจะโพสต์สิ่งที่ฉันมีและพิจารณาคำตอบนี้ให้สมบูรณ์)
[แก้ไข: วิธีแก้ปัญหาด้านบนมีสองด้านที่ควรถูกมองว่าแตกต่าง ขั้นแรกผู้ประกอบการกำหนดโดยผู้ใช้น้ำตาล syntactic ให้โดยการpostcircumfix:<[- ]> (Str ...ประกาศ ประการที่สองร่างกายของคำแถลงนั้น ในตัวอย่างข้างต้นฉันใช้วิธีการแก้ปัญหาของแบรด คำตอบเดิมของฉันอยู่ด้านล่าง]
เนื่องจากคำถามของคุณลดระดับลงเพื่อลบดัชนีบางส่วนของ a [แก้ไข: ผิดต่อคำตอบของแบรด].combและนำjoinผลลัพธ์มาคำถามของคุณจึงซ้ำซ้อนกันเป็น ...
วิธีที่รวดเร็วในการยกเลิกการเลือกอาร์เรย์หรือองค์ประกอบรายการคืออะไร? เพิ่มวิธีแก้ปัญหาเพิ่มเติมสำหรับ.comb ... .joinคำตอบ[ ] ที่นี่
นำมาใช้เป็นสอง multis เพื่อให้สามารถใช้ไวยากรณ์เดียวกันกับPositionals:
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ติดตั้งเป็นเพียงคำตอบของ @ Sebastian เวอร์ชันที่เรียบง่ายขึ้นเล็กน้อย ฉันไม่ได้เปรียบเทียบกับคำตอบของ jnthn จากคำตอบก่อนหน้านี้ที่ฉันลิงก์ไว้ด้านบน แต่ถ้าเร็วกว่านี้ก็สามารถเปลี่ยนเป็นแทนได้ * [แก้ไข: เห็นได้ชัดว่ามันควรจะเป็นทางออกของแบรดสำหรับตัวแปรสตริง] *
อีกรุ่นหนึ่ง:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
นี่คือความใกล้เคียงที่สุดที่ฉันได้รับในแง่ของความเรียบง่ายและความสั้น
say '0123456789'.comb[ |(3..6), |(8..*) ].join
ทุกคนสามารถเปลี่ยนสตริงให้เป็นรายการโดยใช้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มันสร้างวัตถุน้อยที่สุดเท่าที่จะทำได้
my $string='0123456789';
for (1..3, 8).flat.reverse { $string.substr-rw($_, 1) = '' }