베어 본 솔루션
시퀀스의 요점을 인쇄하는 매우 간단한 솔루션부터 시작하겠습니다. 질문에 추가 한 세부 사항은 다루지 않지만 좋은 출발점입니다.
sub seq-range-gist ( @seq ) {
my @pairs = @seq.pairs;
join "\n", @pairs.head(3)».gist, '...', @pairs.tail(2)».gist
}
.kv
그것의 invocant를 형태로 변환하는 것과 달리 , key1, value1, key2, value2, key3, value3, ...
즉 그것의 invocant가 3 개의 요소를 포함하면 6 개의 element .pairs
는 그것의 invocant를 형태로 변환한다 key1 => value1, key2 => value2, key3 => value3, ...
.
내가 사용하는 .pairs
대신 .kv
그것을 그냥 사용할 수있는 것을 의미 부분적으로 있기 때문에 ».gist
쉽게 편안한를 얻을 수있는 코드에서 나중에 key1 => value1
각 요소에 대한 표시. 우리는 아래에서 그것을 수정하지만 이것은 좋은 관용적 시작입니다.
.head
과 .tail
통화가 invocant 목록에서 첫 번째와 마지막 N 요소의 작은 목록을 만들 수있는 관용적 인 방법입니다 (이것은 게으른 아니다 제공, 더 그것에 대해 미주리).
이 초기 솔루션이 제공되면 다음을 say seq-range-gist (0,1 ... Inf)[^10]
표시합니다.
0 => 0
1 => 1
2 => 2
...
8 => 8
9 => 9
다음으로, "인쇄 된 출력에서 첫 번째 요소 만 삭제"할 수 있기를 원합니다. 불행히도 다음을 say seq-range-gist (0,1 ... Inf)[1..9]
표시합니다 :
0 => 1
1 => 2
2 => 3
...
7 => 8
8 => 9
왼쪽의 =>
숫자가 원래 순서의 번호를 유지하기를 원합니다 . 이를 가능하게하기 위해 추출하고자하는 범위에서 기본 시퀀스를 분리합니다. 두 번째 매개 변수 / 인수 @range
를 추가 [@range]
하고 하위의 두 번째 줄에 추가 합니다.
sub seq-range-gist ( @seq, @range ) {
my @pairs = @seq.pairs[@range];
이제 우리는 say seq-range-gist (0,1 ... Inf), 1..9
디스플레이에 쓸 수 있습니다 :
1 => 1
2 => 2
3 => 3
...
8 => 8
9 => 9
귀하의 질문에 당신은 aINDEX = VALUE
대신 형식을 사용했습니다 INDEX => VALUE
. 요점을 사용자 정의 할 수 있도록 세 번째 &gist
루틴 매개 변수 / 인수를 추가 하고 내장 .gist
메소드 대신 호출하십시오 .
sub seq-range-gist ( @seq, @range, :&gist ) {
my @pairs = @seq.pairs[@range];
join "\n", @pairs.head(3)».&gist, '...', @pairs.tail(2)».&gist
}
seq-range-gist
sub 본문에서 "메소드"호출 이 지금 .&gist
은 아니고 어떻게 작동하는지 주목하십시오 .gist
. 구문 .&foo
은 서브 &foo
( foo
왼쪽의 호출자를 서브 .
의 $_
인수로 전달)를 전달 하는 서브 (일반적으로 그냥 작성하여 호출)를 호출합니다 .
또한 &gist
매개 변수 앞에을 붙여 이름을 지정한 매개 변수를 만들었습니다 :
.
이제 다음이 say seq-range-gist (0,1 ... Inf), 1..9, gist => { "a{.key} = {.value}" }
표시됩니다.
a1 = 1
a2 = 2
a3 = 3
...
a8 = 8
a9 = 9
광택 추가
이 답변의 나머지 부분은 광택에 관심이있는 독자에게 보너스 자료입니다.
say seq-range-gist (0, 1, 2, 3), ^3
표시합니다 :
0 => 0
1 => 1
2 => 2
...
1 => 1
2 => 2
죄송합니다. 머리와 꼬리가 결합 된 것보다 더 많은 쌍이 있었더라도 적어도 반복 된 선을 얻지 못했지만 head, ..., tail
한두 가지 요소 만 제거 하는 방법을 사용하면 여전히 의미가 없습니다 . 이러한 문제를 해결하기 위해 하위 본문의 마지막 문장을 변경해 보겠습니다.
join "\n",
@pairs < $head + $tail + 3 # Of course, the 3 is a bit arbitrary
?? @pairs».&gist
!! (@pairs.head($head)».&gist, '...', @pairs.tail($tail)».&gist)
다음으로, 범위 나 요지없이 호출하면 서브가 유용한 것을 수행하면 좋을 것입니다. 우리는 주로 @range
and &gist
매개 변수에 적절한 기본값 을 지정하여 문제를 해결할 수 있습니다 .
sub seq-range-gist (
@seq,
@range = @seq.is-lazy ?? ^100 !! ^@seq,
:&gist = { .gist }
) {
경우 @seq
입니다 하지 게으른 다음 @range
의 전체 범위 기본값 @seq
. 경우 @seq
입니다 무한 (이 경우 그것은 또한 게으른), 다음 100 개까지 기본 괜찮습니다. 그러나 @seq
게으르지 만 정의 된 값이 100보다 작은 경우 어떻게됩니까? 이 경우를 다루기 .grep: *.value.defined
위해 @pairs
선언에 추가 합니다 .
my @pairs = @seq.pairs[@range].grep: *.value.defined;
또 다른 간단한 개선 사항은 선택적인 헤드 및 테일 매개 변수이며 최종 광택 솔루션으로 이어집니다.
sub seq-range-gist (
@seq,
@range = @seq.is-lazy ?? ^100 !! ^@seq,
:$head = 3,
:$tail = 2,
:&gist = { .gist }
) {
my @pairs = @seq.pairs[@range].grep: *.value.defined;
join "\n",
@pairs <= $head + $tail + 2
?? @pairs».&gist
!! (@pairs.head($head)».&gist, '...', @pairs.tail($tail)».&gist)
}