donp: Rekursion vs. Iteration, Mathematische vs. Listen-Operationen

Beitrag lesen

Gestört hat mich übrigens nicht die Verwendung von [], Array-Literale gibt es in vielen Sprachen, sondern die von ||. || ist erstmal ein boolsches Oder, die Verwendung als eine Art Inline-IF ist nicht besonders Erwartungskonform.

Doch, das ist sie. Die Amis nennen "||" in JavaScript auch den "default operator", weil er eben nicht einfach ein boolesches oder ist, sondern den einen oder den anderen Operanden zrückgibt, welchen Typs diese auch immer sein mögen.

"default operator" heißt er deshalb, weil er es erlaubt, den zweiten Operanden als default-Wert zu setzen, falls der erste irgendwie zu "falsch" evaluiert (d.h. "falsy" ist, das muss nicht zwingend false sein, "" oder 0 oder null oder undefined tun´s auch). Das ist auch inline durchaus erlaubt bzw. vorgesehen (warum soll ein "operator" nicht inline verwendet werden?). Solche Dinge machen eine Programmiersprache erst elegant.

Nochmal: a||b ist kein boolesches oder, das immer true oder false liefert, sondern es bedeutet nicht mehr und nicht weniger als if(a){return a}else{return b}. Im Spezialfall mit zwei booelschen Werten a und b enspricht das natürlich dem booleschen oder, aber das ist, wie gesagt, nur ein Spezialfall.

Mein Ausdruck a||[])[0] bedeutet die Existenz (true oder false) des ersten Elements [0] im Array a, welches defaultmässig "||" zum leeren Array wird "[]", falls a nicht definiert sein sollte, was nur beim ersten Aufruf der Funktion eintritt. Das finde ich durchaus elegant ausgedrückt, auch wenn es etwas kryptisch aussieht.
Hast du mal ein Perl-Programm gesehen? Eine sehr elegante Sprache, würde ich sagen, aber vom bloßen Hinsehen müsstest du schon Kopfschmerzen bekommen.

Eine sauber implementierte Variante Deiner vorgehensweise wäre:
function quersumme(n) {
  var s = n.toString();
  var sum = 0;
  for (var i = 0; i < s.length; ++i) {
    sum += s[i];
  }
  return sum < 10 ? sum : quersumme(sum);
}

Das ist doch nicht dasselbe: In dieser "sauberen" Variante wird die übergebene Zahl erst mal in einen String s umgewandelt. Was bedeutet dann eigentlich s[i]? s müsste doch dabei ein Array sein... Aber das ist gar nicht der Punkt, sondern: Im Fall quersumme(1) wird die 1 erst mal zum String gemacht, dann in ein Array geschickt, dann in der Schleife wieder als Zahl (per automatischer Typumwandlung?) zur 0 addiert, bevor du sie endlich fragst, ob sie nicht vielleicht kleiner als 10 ist. Nicht besonders elegant, würde ich sagen.

Meine Funktion macht in diesem Fall nur folgendes: Sie erzeugt ein leeres Array, testet dann ob es ein erstes Element darin gibt (=> natürlich nicht), testet dann sofort, ob sie kleiner als 10 ist (=>natürlich ja), und gibt sie zurück => keinerlei Stringoperationen in diesem Fall, wäre ja auch völlig unnötig.

Weiß nicht, ob du mein anderes Posting gelesen hast, wo die ultimative Lösung drin steht, für alle natürlichen Zahlen n>0:

function quersumme(n){return n%9||9;}

Noch Fragen ;) ?

Don P