インデックスによって文字列から一部の文字を削除します(Raku)


15

FAQ: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;

1行で:

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

(これだけという、オーグメントが悪いと言っているわけではない.&removeことを削除する方法です。
user0721090601

私はあなたの提案に関して非拡張バリアントを追加しました。ありがとうございました。
セバスチャン

1
∖混乱し、バックスラッシュ文字のように見えます。
Shniperson

12
.value.print if .key  !(elem) (1,2,3,8) for '0123456789'.comb.pairs

9

not-at操作の最新のアイデア(以下の実装について説明します):

使用法:

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 ]おなじみの使用すなわち、[...]表記が、左と開封後、追加のマイナスの文字列で[添字内容がリストされていることを示すためにexdicesではなく、インデックス

[編集:元の実装をBradに置き換えました。ブラッド氏が指摘しているように、彼の解決策は「[インデックス]が最低から最高の順であり、重複がないと想定している」ため、おそらくそれは間違った方向にあり、彼はそうは約束しませんが、使用[- ... ]は非常に近いですそうすること。したがって、この構文糖が誰かによって使用される場合、おそらくブラッドのソリューションを使用すべきではありません。おそらく、ブラッドの仮定を排除する方法があるでしょう。]

この構文のような私が、ラリーが意図的になかったことを認識していないの使用で構築し[...]たインデックスの文字列にはので、おそらくここで私の構文は、広く採用には不適切です。おそらく、いくつかの異なるブラケット文字が使用された方が良いでしょう。しかし、私は単純なポストサーカムフィックス構文の使用が良いと思います。

(私もs [ ... ]とまったく同じ方法で文字列のインデックスを作成するストレートバリアントを実装しようとしましたPositionalが、今夜、私を超えた理由で[+ ... ]機能しませんでした。私にはまったく意味がありません!とにかく、私は自分が持っているものを投稿し、この答えは完全だと考えます。


[編集:上記のソリューションには2つの側面があり、これらを区別する必要があります。まず、ユーザー定義の演算子であるpostcircumfix:<[- ]> (Str ...、宣言によって提供される構文糖衣。次に、その宣言の本文です。上記では、ブラッドのソリューション(の変形)を使用しました。私の元の答えは以下です。]


あなたの質問は、いくつかのインデックスを削除するに帰着ため.comb、および再join結果をINGの、あなたの質問は基本的に...重複して [編集:間違った、ブラッドの答えあたり]

配列またはリスト要素の選択を解除する簡単な方法は何ですか?.comb ... .joinここに[ ]回答のさらに多くのソリューションを追加します。


2つのマルチとして実装されているため、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実装は、セバスチャンの答え@のわずかに単純化したバージョンです。上記でリンクした以前の回答からjnthnのソリューションに対してベンチマークを行っていませんが、それが速い場合は、代わりに交換できます。* [編集:明らかに、文字列バリアント代わりにBradのソリューションにする必要があります。] *


「私は、単純なポストサーカムフィックス構文の使用が良いと思います」。絶対に !私はこのソリューションが大好きです。
ティンマリーノ

8

さらに別のバリアント:

print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;

.print for ((0..9) (-) (1,2,3,8)).keys;

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、作成されるオブジェクトはできるだけ少なくなります。
Brad Gilbert

「元の文字列を指す部分文字列オブジェクト」:Strを不変として実装することが決定されたのはなぜですか?とにかく印象的な最適化。
Tinmarino

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.