Veränderlicher Zustand und Schleifen. Sie brauchen sie fast nie und Sie bekommen fast immer besseren Code ohne sie.
Dies wird beispielsweise direkt von einem StackOverflow-Thread übernommen:
// 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
Sie machen beide dasselbe. Aber ich habe keine Ahnung, was sie tun. Glücklicherweise erklärt die Frage tatsächlich, was sie tun, sodass ich sie wie folgt umschreiben konnte:
// 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);
Es gibt keine Schleifen und keinen veränderlichen Zustand. Okay, keine expliziten Schleifen und keine Schleifenzähler.
Der Code ist viel kürzer, viel einfacher, viel weniger fehleranfällig als vielmehr eine Beschreibung dessen, was der Code tun soll (insbesondere im Ruby-Fall sagt er ziemlich direkt "Gruppiere die Dinge nach Typ"). Es besteht keine Gefahr, dass das Ende des Arrays verrutscht, Zaunpfostenfehler oder einzelne Fehler mit den Schleifenindizes und Beendigungsbedingungen auftreten, da keine Schleifenindizes und Beendigungsbedingungen vorliegen.