मान लीजिए हमें संख्याओं के एक ऐरे को जोड़ना है। इसे करने के कई तरीके हैं।
कई भाषाओं में इस समस्या को एक्युमुलेटर वेरिएबल वाले लूप के रूप में लिखा जाता है।
इस समस्या को एक रिकर्सिव फंक्शन के रूप में भी लिखा जा सकता है। स्यूडोकोड में यह कुछ ऐसा दिखेगा।
function Add(X, Sum=0):
if X is empty then
return Sum
else
return Add(rest(X), Sum + first(X))
end
end
समस्या को छोटे-छोटे हिस्सों में बाँटने के इस तरीके को "बेस केस की ओर घटते जाना" भी कहा जाता है।
Reduce किसी डेटा स्ट्रक्चर के सारे एलिमेंट को मिलाकर एक ही वैल्यू बनाने का तरीका है। इस प्रक्रिया में डेटा स्ट्रक्चर के हर एलिमेंट पर एक-एक करके फंक्शन लगाया जाता है। हर बार लगाया गया यह फंक्शन जमा होते परिणाम को बदल देता है।
jq में यह प्रक्रिया reduce फिल्टर में लागू की गई है।
अन्य भाषाओं में इसे "fold", "fold-left", "inject" या "aggregate" भी कहा जाता है।
jq का reduce एक्सप्रेशन ऐसा दिखता है।
reduce STREAM_EXPRESSION as $var (INITIAL_VALUE; UPDATE_EXPRESSION)
STREAM_EXPRESSION चीज़ों की एक स्ट्रीम है, जिसमें हर चीज़ बारी-बारी से $var वेरिएबल में रखी जाती है।
.[] इस्तेमाल कीजिए: $myArray | .[]।INITIAL_VALUE जमा होते परिणाम की शुरुआती वैल्यू है (जिसे "एक्युमुलेटर" कहा जाता है)।UPDATE_EXPRESSION मौजूदा वैल्यू ($var) को एक्युमुलेटर में मिला देता है (यानी उसे "fold" करता है)।
. एक्युमुलेटर की वैल्यू होती है।reduce का आउटपुट होता है।चलिए एक उदाहरण देखते हैं: एक ऐरे की संख्याओं को जोड़ना।
add फिल्टर यही काम करता है, लेकिन हम देखेंगे कि इसे खुद कैसे बनाते हैं।
अगर हम [10, 20, 30, 40] को इनपुट बनाएँ और शून्य को शुरुआती स्थिति मानें, तो हर कदम ऐसा दिखता है।
| # | स्थिति | एलिमेंट | रिड्यूसर | परिणाम |
|---|---|---|---|---|
| 1 | 0 | 10 | 0 + 10 | 10 |
| 2 | 10 | 20 | 10 + 20 | 30 |
| 3 | 30 | 30 | 30 + 30 | 60 |
| 4 | 60 | 40 | 60 + 40 | 100 |
jq के सिंटैक्स में यह इस कोड जैसा दिखता है।
0 + 10 | . + 20 | . + 30 | . + 40
हम इसे reduce फिल्टर से लिख सकते हैं।
[10, 20, 30, 40] | reduce .[] as $n (0; . + $n) # => 100
add बिल्टइन वास्तव में reduce से बनाया गया है, लेकिन यह "null" को शुरुआती स्थिति मानता है (किसी भी डेटा टाइप को null में जोड़ा जा सकता है)।
def add: reduce .[] as $x (null; . + $x);
रिड्यूस करने वाले एक्सप्रेशन में . ही एक्युमुलेटर होता है।
अगर इनपुट कोई ऐसा ऑब्जेक्ट है जिसका इस्तेमाल आपको रिड्यूस करने वाले फंक्शन के अंदर करना है, तो उसे एक वेरिएबल में रखना पड़ेगा।
{"apple": 10, "banana": 16, "carrot": 4}
| . as $obj
| reduce (keys | .[]) as $key (0; . + $obj[$key]) # => 30
एक्युमुलेटर किसी भी डेटा टाइप का हो सकता है। उदाहरण के लिए, आपको किसी ऐरे को उल्टा करना हो सकता है।
["A", "B", "C", "D"]
| reduce .[] as $elem ([]; [$elem] + .) # => ["D", "C", "B", "A"]