Array.prototype.flatMap()

Il metodo flatMap() prima mappa ogni elemento eseguendo la funzione per passata come parametro, poi appiattisce il risultato in un nuovo array. Il comportamento è identico a una chiamata a  map() seguita da un flat() con profondità 1, ma flatMap() in questo caso è la soluzione migliore perché è più efficente delle due chiamate separate.

Sintassi

var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
    // restituisci un elemento per il nuovo array
}[, thisArg])

Parametri

callback
Funzione per produrre un elemento del nuovo Array, prevede a sua volta tre parametri:
currentValue
L'elemento che si sta processando.
indexOptional
L'indice dell'elemento corrente.
arrayOptional
L'array che si sta processando con map.
thisArgOptional
Valore usato come this mentre si esegue la callback.

Risultato

Un nuovo array i cui elementi sono il risultato della chiamata a callback, "appiattiti" ad una profondità di 1

Descrizione

Guarda Array.prototype.map() per una descrizione dettagliata della funzione callback. flatMap è identico a una chiamata a map seguita da una chiamata flat con una profondità di 1.

Esempi

map()flatMap()

let arr1 = [1, 2, 3, 4];

arr1.map(x => [x * 2]); 
// [[2], [4], [6], [8]]

arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]

// viene appiattito un solo elemento
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]

Lo stesso risultato lo si può ottenere anche con la sola chiamata a map, di seguito è riportato un esempio migliore di uso di flatMap.

Viene generata una lista di parole da una lista di frasi.

let arr1 = ["it's Sunny in", "", "California"];

arr1.map(x => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]

arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]

Notare che, a differenza di map da solo, la lunghezza dell'output è diversa tra le due chiamate e in particolare il risultato di flatMap non avrà la stessa lunghezza dell'input.

Aggiungere e rimuovere elementi durante l'esecuzione di map()

flatMap può essere usato per aggiungere e rimuovere elementi durante l'esecuzione di map. In altre parole, offre la possibilità di mappare molti a molti (processando ogni input separatamente), anziché sempre uno a uno. In questo senso lavora come opposto di filter. Basta restituire un array con un solo elemento per mantenere l'oggetto invariato, un array con più elementi, invece, aggiungerà questi al risultato, un array vuoto per rimuovere l'elemento corrente.

// Per rimuovere i numeri negativi e dividere i numeri dispari in un numero pari e un 1
let a = [5, 4, -3, 20, 17, -33, -4, 18]
//       |\  \  x   |  | \   x   x   |
//      [4,1, 4,   20, 16, 1,       18]

a.flatMap( (n) =>
  (n < 0) ?      [] :
  (n % 2 == 0) ? [n] :
                 [n-1, 1]
)

// expected output: [4, 1, 4, 20, 16, 1, 18]

Alternative

reduce() and concat()

var arr = [1, 2, 3, 4];

arr.flatMap(x => [x, x * 2]);
// si ottiene lo stesso risultato con
arr.reduce((acc, x) => acc.concat([x, x * 2]), []);
// [1, 2, 2, 4, 3, 6, 4, 8]

Notare che questa soluzione non è efficente e non dovrebbe essere usata per array di grandi dimensioni: in ogni iterazione viene creato un nuovo array temporaneo che dovrà essere deallocato dal garbae collector, e copia gli elementi dall'array corrente (acc), in un nuovo array ad ogni iterazione invece di aggiungerli ad uno preesistente.

Specifiche

Specifica
ECMAScript Latest Draft (ECMA-262)
The definition of 'Array.prototype.flatMap' in that specification.

Compatibilità browser

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
flatMapChrome Full support 69Edge No support NoFirefox Full support 62IE No support NoOpera Full support 56Safari Full support 12WebView Android Full support 69Chrome Android Full support 69Firefox Android Full support 62Opera Android Full support 48Safari iOS Full support 12Samsung Internet Android Full support 10.0nodejs Full support 11.0.0

Legend

Full support  
Full support
No support  
No support

Vedi anche