입력에 짝수 개의 요소가 있습니다.
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
가 발생 하면 두 개의 하위 목록이 표시됩니다 . 그리고 비슷한 맥락에서 아마도 다음과 같은 입력으로 0이 아닌 두 개의 일치 항목을보고 싶을 것입니다.
<1 2 2 3 3 4>
따라서 이러한 문제를 해결하는 솔루션에 중점을 두겠습니다.
추가 문제를 해결하기위한 솔루션 공간의 축소에도 불구하고 솔루션을 기능적으로 표현하는 방법은 여전히 많습니다.
끝에 더 많은 코드를 추가하는 한 가지 방법은 다음과 같습니다.
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))
. 길이 인수가 쌍인 경우 키는 길이이고 값은 다음 쌍을 시작하기위한 오프셋입니다. 오프셋이 음수이면 하위 목록이 겹칩니다. 따라서 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
각 쌍은 invocant리스트의 요소의 인덱스이고; 는 .value
요소의 값이다.
.value xx 2
쓸 수있었습니다 .value, .value
. (참조 xx
)
@s - 1
@s
빼기 1 의 요소 수입니다 .
[eq]
의는 [eq] list
A는 감소 .
연속적인 동일한 요소를 구성하는 요소를 결정하기 위해 텍스트 패턴 일치가 필요한 경우 입력 목록을 문자열로 변환하고 일치 목록을 생성하는 일치 부사 중 하나를 사용하여 일치시키는 다음 결과 일치 목록에서 원하는 결과로 매핑하십시오. 결과. 오버랩과 일치 시키려면 (예 : 사용중인 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
상당히 맞는 것 같다. 실제로이 유형의 작업에 가장 적합한 것일 수도 있습니다.