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.assign
su 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 reduce
un 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 reduce
metodo accetta due parametri,
Array.prototype.reduce( callback, initialItem )
La callback
funzione accetta i seguenti parametri
(accumulator, itemInArray, indexInArray, entireArray) => { /* do stuff */ }
Per la prima iterazione,
Se initialItem
viene fornita, la reduce
funzione passa initialItem
come accumulator
e 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.reduce
initialItem
itemInArray
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.