入力に含まれる要素の数は偶数です:
say elems <1 1 0 2 0 2 1 2 2 2 4 4 3 3>; # 14
あなたのgrep
ブロックには、二つの要素ごとに消費します:
{$^a eq $^b}
したがって、要素を追加または削除すると、最後に残った単一の要素でブロックが実行されたときに取得するエラーが発生します。
問題を解決する方法はたくさんあります。
しかし、オーバーラップを許可するオプションについても尋ねたため、たとえば、(2 2)
シーケンス2 2 2
が検出されたときに2つのサブリストが表示されます。そして、同様に、おそらく次のような入力で、ゼロではなく2つの一致を表示する必要があります。
<1 2 2 3 3 4>
したがって、これらの問題にも対処するソリューションに焦点を当てます。
余分な問題に対処するためのソリューションスペースの狭小化にもかかわらず、ソリューションを機能的に表現する方法はまだたくさんあります。
あなたの最後にもう少しコードを追加する1つの方法:
my @s = <1 1 0 2 0 2 1 2 2 2 4 4 3 3>;
say grep {$^a eq $^b}, @s .rotor( 2 => -1 ) .flat
この.rotor
メソッドは、リストを、同じ長さのサブリストのリストに変換します。たとえば、をsay <1 2 3 4> .rotor: 2
表示します((1 2) (3 4))
。length引数がペアの場合、キーは長さで、値は次のペアを開始するためのオフセットです。オフセットが負の場合、サブリストが重複します。したがって、がsay <1 2 3 4> .rotor: 2 => -1
表示されます((1 2) (2 3) (3 4))
。
この.flat
メソッドは、その呼び出し元を「平坦化」します。たとえば、をsay ((1,2),(2,3),(3,4)) .flat
表示します(1 2 2 3 3 4)
。
上記の解決策を書くためのおそらくもっと読みやすい方法は、を省略しflat
て使用し.[0]
、.[1]
によって返されるサブリストにインデックスを付けることrotor
です。
say @s .rotor( 2 => -1 ) .grep: { .[0] eq .[1] }
サブリストのサイズを一般化する別のバリエーションについては、Elizabeth Mattijsenのコメントも参照してください。
より一般的なコーディングパターンが必要な場合は、次のように記述します。
say @s .pairs .map: { .value xx 2 if .key < @s - 1 and [eq] @s[.key,.key+1] }
.pairs
リストのメソッドはペアのリストを返します。各ペアは、その呼び出し元リストの各要素に対応しています。.key
各対のインボカントリストにおける要素のインデックスです。これ.value
は要素の値です。
.value xx 2
書かれている可能性があります.value, .value
。(を参照してくださいxx
。)
@s - 1
@s
マイナス1 の要素数です。
[eq]
中には[eq] list
あるの減少。
連続する等しい要素を構成するものを決定するためにテキストパターンマッチングが必要な場合は、入力リストを文字列に変換し、一致のリストを生成する一致副詞の1つを使用して一致させ、結果の一致リストから目的のリストにマッピングします。結果。オーバーラップと照合するには(たとえば2 2 2
、((2 2) (2 2))
使用中の結果:ov
:
say @s .Str .match( / (.) ' ' $0 /, :ov ) .map: { .[0].Str xx 2 }
2 2 2 2
3(2 2)
秒が出力されます。rotor
最初にメソッドを思いついて、そのsquish
ような機能や引数@s.squish(:length 2, :multiple_instances yes)
があるかどうかを確認したが、そのような機能がなく、タスクに適さなかったという方法を聞いたことがない。比較するとsquish
、rotor
かなりフィットらしいです。実際には、このタイプの操作に最も適したものになる可能性もあります。