परस्पर अवस्था और छोरें। आपको लगभग उनकी आवश्यकता कभी नहीं होती है, और आप लगभग हमेशा उनके बिना बेहतर कोड प्राप्त करते हैं।
उदाहरण के लिए, इसे सीधे StackOverflow थ्रेड से लिया गया है:
// ECMAScript
var thing, things_by_type = {};
for (var i = 0; i < things.length; i++) {
thing = things[i];
if(things_by_type[thing.type]) {
things_by_type[thing.type].push(thing);
} else {
things_by_type[thing.type] = [thing];
}
}
# Ruby
things_by_type = {}
things.each do |thing|
(things_by_type[thing.type] ||= []) << thing
end
वे दोनों एक ही काम कर रहे हैं। लेकिन मुझे नहीं पता कि वे क्या कर रहे हैं। सौभाग्य से, सवाल वास्तव में बताता है कि वे क्या कर रहे हैं, इसलिए मैं उन्हें निम्नानुसार फिर से लिखने में सक्षम था:
// ECMAScript
things.reduce(function (acc, thing) {
(acc[thing.type] || (acc[thing.type] = [])).push(thing);
return acc;
}, {});
# Ruby
things.group_by(&:type)
// Scala
things groupBy(_.type)
// C#
from thing in things group thing by thing.Type // or
things.GroupBy(thing => thing.Type);
कोई लूप नहीं है, और कोई भी परिवर्तनशील स्थिति नहीं है। ठीक है, ठीक है, कोई स्पष्ट लूप और कोई लूप काउंटर नहीं।
कोड बहुत कम, बहुत सरल हो गया है, बहुत कुछ इस तरह का वर्णन है कि कोड क्या करना चाहिए (विशेषकर रूबी मामले में यह बहुत सीधे तौर पर "प्रकार द्वारा चीजों को समूह"), और बहुत कम त्रुटि-प्रवण कहता है। वहाँ सरणी के अंत चलाने का कोई खतरा नहीं है, fencepost त्रुटियों या बंद-एक करके पाश सूचकांक और समाप्ति शर्तों के साथ त्रुटियों, क्योंकि वहाँ नहीं कर रहे हैं पाश सूचकांक और समाप्ति की स्थिति।