ลบอักขระบางตัวออกจากสตริงโดยดัชนี (Raku)


15

คำถามที่พบบ่อย: ใน Raku คุณจะลบอักขระบางตัวออกจากสตริงตามดัชนีของพวกเขาได้อย่างไร

ว่าฉันต้องการลบดัชนี 1 ถึง 3 และ 8

xxx("0123456789", (1..3, 8).flat);  # 045679

คำตอบ:


14

ตัวแปรของ 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);

ที่แก้ปัญหาได้อย่างสมบูรณ์ในความคิดของฉัน ขอขอบคุณที่เตือนว่า \ และ (-) เทียบเท่ากัน ฉันไม่เห็นวิธีอื่นในการฝานด้วยดัชนีที่ฉันไม่ต้องการและไม่ใช่ดัชนีที่ฉันต้องการ
Tinmarino

1
คุณไม่จำเป็นต้องใช้MONKET-TYPINGถ้าคุณเพียงแค่ทำให้มันเป็นอิสระลอยตัวและเรียกมันว่า'foobar'.&remove: (1..2, 4); (augment สามารถมีปัญหากับการจัดเรียงถ้าใช้หลายครั้ง)
user0721090601

(ซึ่งไม่ได้บอกว่า augment ไม่ดีเพียงแค่.&removeวิธีการลบนั้น
user0721090601

ฉันได้เพิ่มชุดตัวเลือกที่ไม่เสริมเข้ากับข้อเสนอแนะของคุณ ขอบคุณ.
เซบาสเตียน

1
∖สับสนและดูเหมือนว่าเป็นอักขระเครื่องหมายทับขวา
Shniperson


9

แนวคิดล่าสุดของฉันสำหรับการดำเนินการที่ไม่ใช่ (ฉันจะกล่าวถึงการติดตั้งด้านล่าง):

การใช้งาน:

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 จากคำตอบก่อนหน้านี้ที่ฉันลิงก์ไว้ด้านบน แต่ถ้าเร็วกว่านี้ก็สามารถเปลี่ยนเป็นแทนได้ * [แก้ไข: เห็นได้ชัดว่ามันควรจะเป็นทางออกของแบรดสำหรับตัวแปรสตริง] *


"ฉันคิดว่าการใช้ซินแท็กซ์ postcircumfix อย่างง่ายนั้นดี" อย่างแน่นอน ! ฉันชอบวิธีนี้: อ่านง่ายสุด ๆ
Tinmarino


8

นี่คือความใกล้เคียงที่สุดที่ฉันได้รับในแง่ของความเรียบง่ายและความสั้น

say '0123456789'.comb[ |(3..6), |(8..*) ].join

7

ทุกคนสามารถเปลี่ยนสตริงให้เป็นรายการโดยใช้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

ด้านบนถือว่าดัชนีอยู่ในลำดับจากต่ำสุดไปหาสูงสุดและไม่มีการทับซ้อนกัน


นี่คือคำตอบที่เร็วที่สุดโดยปัจจัยที่ 150 ในเครื่องของฉัน (ด้วยmy $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat) หวียาวสำหรับสตริงยาวขอบคุณ @BradGilbert นี่จะช่วยให้บางคนอย่างน้อยฉัน :-)
Tinmarino

1
@Tinmarino นั่นเป็นเพราะ MoarVM มักจะไม่คัดลอกสตริง แต่มันจะสร้างวัตถุซับสตริงที่ชี้ไปที่สตริงเดิม เมื่อคุณใช้.combมันจะต้องสร้างวัตถุเหล่านั้นจำนวนมากและรวมกลับเข้าด้วยกัน ด้วยsubstrมันสร้างวัตถุน้อยที่สุดเท่าที่จะทำได้
แบรดกิลเบิร์ต

"วัตถุซับสตริงที่ชี้ไปที่สตริงต้นฉบับ": นั่นเป็นเหตุผลว่าทำไมจึงเลือกใช้ Str เป็นไม่เปลี่ยนรูป การเพิ่มประสิทธิภาพที่น่าประทับใจอยู่ดี
Tinmarino

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.