Taschenrechner erstellen (JS)

Sep 30 2020

Ich habe eine Zeile calc(2).add(3).add(5).res()und muss eine Lösung schreiben, damit ich 10als Ergebnis habe. Ich habe es versucht

class Calc{
    constructor(num){
        this.num = num
    }

    add(a){
        this.num += a;
        return this;
    }

    res() {
        return this.num;
    }
}
let calc = new Calc(2)
console.log(calc.add(3).add(5).res())

aber in meinem Fall gehe ich 2in new Calc(2), nicht in calc(2). Wie kann ich das ändern?

Wird für jede Hilfe wirklich dankbar sein!

Antworten

1 VLAZ Sep 30 2020 at 19:26

Sie können eine elegante Lösung finden, die die Kraft von Verschlüssen nutzt:

function calc(x) {
  return {
    res: function() {
      return x;
    },
    add: function(y) {
      return calc(x + y)
    }
  }
}

test(
  10,
  calc(10).res()
);
test(
  10,
  calc(3).add(7).res()
);
test(
  10,
  calc(8).add(2).res()
);
test(
  10,
  calc(2).add(3).add(5).res()
);


function test(expected, actual) {
  console.log(
`result is: ${actual} correct: ${actual === expected}
`)
}

Die calcFunktion nimmt die aufgerufene Anfangsnummer xund gibt ein Objekt mit zwei Methoden zurück:

  • res() gibt nur die Nummer zurück
  • add()nimmt einen Parameter y, summiert ihn mit xund ruft calcerneut mit dem Ergebnis auf.

So Ihre Schnittstelle ist völlig im Einklang: calc(10)wird das gleiche wie sein calc(3).add(7)oder calc(8).add(2)oder calc(2).add(3).add(5). Sie können die addAnrufe so oft verketten, wie Sie möchten, und es wird immer dasselbe sein. Wenn res()Sie anrufen, wird die Kette beendet und Sie erhalten nur die calcaktuell gültige Nummer - unabhängig davon, ob Sie dies getan haben calc(10).res()oder nicht calc(2).add(3).add(5).res().

Der Code kann mit Pfeilfunktionen stark gekürzt werden:

const calc = x => ({
  res: () => x,
  add: y => calc(x + y)
});

test(
  10,
  calc(10).res()
);
test(
  10,
  calc(3).add(7).res()
);
test(
  10,
  calc(8).add(2).res()
);
test(
  10,
  calc(2).add(3).add(5).res()
);


function test(expected, actual) {
  console.log(
`result is: ${actual} correct: ${actual === expected}
`)
}

Andere Operationen können ebenfalls einfach mit demselben Muster hinzugefügt werden:

const calc = x => ({
  res: () => x,
  add: y => calc(x + y),
  sub: y => calc(x - y),
  mul: y => calc(x * y),
  div: y => calc(x / y)
});

test(
  2,
  calc(5).add(5).mul(2).sub(4).div(8).res()
  // (((5 + 5) * 2) - 4) / 8 = 
  // ((10 * 2) - 4) / 8 = 
  // (20 - 4) / 8 = 
  // 16 / 8 = 2
);


function test(expected, actual) {
  console.log(
`result is: ${actual} correct: ${actual === expected}
`)
}

Da jede Operation sofort ausgeführt wird, haben Sie derzeit nur den Vorrang.

3 alotropico Sep 30 2020 at 18:46

Wenn ich richtig verstanden hätte, wäre dies ein Weg, dies zu tun:

class Calc{
    constructor(num){
        this.num = num
    }

    add(a){
        this.num += a;
        return this;
    }

    res() {
        return this.num;
    }
}
let calc = function(num){ return new Calc(num) }
console.log(calc(2).add(3).add(5).res())

DerekWang Sep 30 2020 at 18:49

Sie können calcals Funktion definieren , die das Calc-Objekt zurückgibt.

class Calc{
    constructor(num){
        this.num = num
    }

    add(a){
        this.num += a;
        return this;
    }

    res() {
        return this.num;
    }
}

const calc = (input) => new Calc(input);
console.log(calc(2).add(3).add(5).res())