एक नंगे पैर समाधान
आइए एक अनुक्रम के एक जिस्ट को प्रिंट करने के लिए एक बहुत ही सरल समाधान के साथ शुरू करें। यह आपके द्वारा अपने प्रश्न में जोड़े गए विशेषकों से नहीं निपटता है लेकिन यह एक अच्छा प्रारंभिक बिंदु है:
sub seq-range-gist ( @seq ) {
my @pairs = @seq.pairs;
join "\n", @pairs.head(3)».gist, '...', @pairs.tail(2)».gist
}
इसके विपरीत .kv, जो अपने इनवोकेंट को फॉर्म में परिवर्तित करता है key1, value1, key2, value2, key3, value3, ..., यानी 6 तत्वों को अगर इसके इनवोकेंट में 3 तत्व हैं, तो .pairsअपने इनवोकेंट को फॉर्म में परिवर्तित करता है key1 => value1, key2 => value2, key3 => value3, ...।
मैंने आंशिक रूप से .pairsइसके बजाय उपयोग किया .kvक्योंकि इसका मतलब था कि मैं ».gistबाद में कोड में बाद में आसानी से key1 => value1प्रत्येक तत्व के लिए एक अच्छा प्रदर्शन प्राप्त कर सकता था । हम इसे नीचे संशोधित करेंगे लेकिन यह एक अच्छी मुहावरेदार शुरुआत है।
.headऔर .tailकॉल मुहावरेदार तरह से एक invocant सूची से पहली और आखिरी एन तत्वों की छोटी सूची बनाने के लिए कर रहे हैं (बशर्ते वह आलसी नहीं है, के बारे में अधिक एक मो में)।
इस प्रारंभिक समाधान को देखते हुए, 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उप अब कर रहे हैं .&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और &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)
}