एक नंगे पैर समाधान
आइए एक अनुक्रम के एक जिस्ट को प्रिंट करने के लिए एक बहुत ही सरल समाधान के साथ शुरू करें। यह आपके द्वारा अपने प्रश्न में जोड़े गए विशेषकों से नहीं निपटता है लेकिन यह एक अच्छा प्रारंभिक बिंदु है:
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)
}