TL; DR, imposta il valore iniziale
Usando la destrutturazione
arr.reduce( ( sum, { x } ) => sum + x , 0)
Senza destrutturare
arr.reduce( ( sum , cur ) => sum + cur.x , 0)
Con dattiloscritto
arr.reduce( ( sum, { x } : { x: number } ) => sum + x , 0)
Proviamo il metodo di destrutturazione:
const arr = [ { x: 1 }, { x: 2 }, { x: 4 } ]
const result = arr.reduce( ( sum, { x } ) => sum + x , 0)
console.log( result ) // 7
La chiave di ciò è l'impostazione del valore iniziale. Il valore restituito diventa il primo parametro della successiva iterazione.
La tecnica utilizzata nella risposta migliore non è idiomatica
La risposta accettata propone di NON passare il valore "opzionale". Questo è sbagliato, poiché il modo idiomatico è che il secondo parametro sia sempre incluso. Perché? Tre motivi:
1. Pericoloso
: non passare il valore iniziale è pericoloso e può creare effetti collaterali e mutazioni se la funzione di richiamata è trascurata.
Ecco
const badCallback = (a,i) => Object.assign(a,i)
const foo = [ { a: 1 }, { b: 2 }, { c: 3 } ]
const bar = foo.reduce( badCallback ) // bad use of Object.assign
// Look, we've tampered with the original array
foo // [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]
Se tuttavia lo avessimo fatto in questo modo, con il valore iniziale:
const bar = foo.reduce( badCallback, {})
// foo is still OK
foo // { a: 1, b: 2, c: 3 }
Per la cronaca, a meno che non si intenda mutare l'oggetto originale, impostare il primo parametro su Object.assignsu un oggetto vuoto. Come questo:Object.assign({}, a, b, c) .
2 - Migliore inferenza del tipo
quando si utilizza uno strumento come Typescript o un editor come VS Code, si ottiene il vantaggio di dire al compilatore l'iniziale e che può rilevare errori se si sbaglia. Se non imposti il valore iniziale, in molte situazioni potrebbe non essere in grado di indovinare e potresti finire con errori di runtime inquietanti.
3 - Rispetta i comportamenti
- JavaScript brilla meglio quando viene liberato il suo bambino funzionale interno. Nel mondo funzionale, esiste uno standard su come "piegare" o reduceun array. Quando pieghi o applichi un catamorfismo all'array, prendi i valori di quell'array per costruire un nuovo tipo. Devi comunicare il tipo risultante: dovresti farlo anche se il tipo finale è quello dei valori nell'array, in un altro array o in qualsiasi altro tipo.
Pensiamo in un altro modo. In JavaScript, le funzioni possono essere passate come dati, ecco come funzionano i callback, qual è il risultato del seguente codice?
[1,2,3].reduce(callback)
Restituirà un numero? Un oggetto? Questo lo rende più chiaro
[1,2,3].reduce(callback,0)
Maggiori informazioni sulle specifiche di programmazione funzionale qui: https://github.com/fantasyland/fantasy-land#foldable
Qualche altro sfondo
Il reducemetodo accetta due parametri,
Array.prototype.reduce( callback, initialItem )
La callbackfunzione accetta i seguenti parametri
(accumulator, itemInArray, indexInArray, entireArray) => { /* do stuff */ }
Per la prima iterazione,
Se initialItemviene fornita, la reducefunzione passa initialItemcome accumulatore il primo elemento dell'array come itemInArray.
Se noninitialItem viene fornito, la funzione passa il primo elemento nell'array come il secondo elemento nell'array in quanto ciò può creare un comportamento confuso.reduceinitialItemitemInArray
Insegno e consiglio di impostare sempre il valore iniziale di ridurre.
Puoi consultare la documentazione su:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Spero che questo ti aiuti!
arr.reduce(function(a,b){return a + b})nel secondo esempio.