Crea calcolatrice (JS)
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
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 numeroadd()avrà un parametroy, riassume conxe invitacalcancora 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.
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())
È 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())