Crea calcolatrice (JS)

Sep 30 2020

Ho una riga calc(2).add(3).add(5).res()e ho bisogno di scrivere una soluzione in modo da avere 10come risultato. Ho provato questo

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())

ma nel mio caso 2entro new Calc(2), non dentro calc(2). Come posso cambiarlo?

Sarò davvero grato per qualsiasi aiuto!

Risposte

1 VLAZ Sep 30 2020 at 19:26

Puoi avere una soluzione elegante che sfrutta la potenza delle chiusure:

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}
`)
}

La calcfunzione prende il numero iniziale chiamato xe restituisce un oggetto con due metodi:

  • res() restituisce solo il numero
  • add()avrà un parametro y, riassume con xe invita calcancora una volta con il risultato.

Quindi la tua interfaccia è del tutto coerente: calc(10)sarà la stessa di calc(3).add(7)o calc(8).add(2)o calc(2).add(3).add(5). Puoi concatenare le addchiamate quanto vuoi e sarà sempre lo stesso. La chiamata res()terminerà la catena e ti darà solo il numero che calcattualmente detiene, che tu abbia fatto calc(10).res()o calc(2).add(3).add(5).res().

Il codice può essere accorciato molto usando le funzioni delle frecce:

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}
`)
}

Altre operazioni possono anche essere facilmente aggiunte utilizzando lo stesso modello:

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}
`)
}

Nota che poiché ogni operazione viene eseguita immediatamente, l'unica precedenza che hai attualmente è quella che viene prima.

3 alotropico Sep 30 2020 at 18:46

Se ho capito bene, questo sarebbe un modo per farlo:

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

È possibile definire calccome funzione che restituisce l'oggetto Calc.

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())