89 votes

Pourquoi pas un Tableau.le prototype.flatMap en javascript?

flatMap est incroyablement utile sur les collections, javascript, mais ne fournit pas un, tout en ayant Array.prototype.map. Pourquoi?

Est-il possible d'émuler flatMap en javascript à la fois facile et efficace w/o la définition d' flatMap manuellement?

108voto

naomik Points 10423

Pourquoi pas un Tableau.le prototype.flatMap en javascript?

Parce que la programmation n'est pas de la magie et toutes les langues n'ont pas de caractéristiques ou de primitives que chaque langue a

Ce qui compte c'est

JavaScript vous donne la possibilité de définir vos propres moyens

const concat = (x,y) =>
  x.concat(y)

const flatMap = (f,xs) =>
  xs.map(f).reduce(concat, [])

const xs = [1,2,3]

console.log(flatMap(x => [x-1, x, x+1], xs))

Ou une réécriture qui s'effondre les deux boucles dans un

const flatMap = (f,xs) =>
  xs.reduce((acc,x) =>
    acc.concat(f(x)), [])

const xs = [1,2,3]

console.log(flatMap(x => [x-1, x, x+1], xs))

Si vous le souhaitez sur l' Array.prototype, rien ne vous en empêche

const concat = (x,y) =>
  x.concat(y)

const flatMap = (f,xs) =>
  xs.map(f).reduce(concat, [])

Array.prototype.flatMap = function(f) {
  return flatMap(f,this)
}

const xs = [1,2,3]

console.log(xs.flatMap(x => [x-1, x, x+1]))

Mise à jour: Array.prototype.flatMap est sur son chemin natif ECMAScript. Il est actuellement en phase-3.

51voto

Kutyel Points 4157

Je pense que c'est un grand moment pour annoncer qu' flatMap a été proposé à la TC39

11voto

Alan Mimms Points 409

Je sais que vous avez dit que vous ne vouliez pas le définir vous-même, mais cette mise en œuvre est assez trivial définition.

Il y a aussi ce à partir de la même page github:

Ici, c'est un peu plus court chemin à l'aide es6 propagation, semblable à renaudtertrais mais à l'aide de es6 et de ne pas aggraver le prototype.

var flatMap = (a, cb) => [].concat(...a.map(cb))

const s = (v) => v.split(',')
const arr = ['cat,dog', 'fish,bird']

flatMap(arr, s)

Serait une de ces aider?

Il convient de noter (merci à @ftor) que cette dernière "solution", souffre de "le Maximum de la pile des appels taille dépassé" si elle est appelée sur une très large (par exemple, 300k éléments) array a.

7voto

Matthew Marichiba Points 954

Lodash fournit un flatmap fonction, qui pour moi, est pratiquement équivalent à Javascript fournir nativement. Si vous n'êtes pas un Lodash de l'utilisateur, puis de l'ES6 Array.reduce() méthode peut vous donner le même résultat, mais vous avez la carte-puis-aplatir par étapes discrètes.

Ci-dessous est un exemple de chaque méthode, le mappage d'une liste d'entiers et retourne uniquement la cote.

Lodash:

_.flatMap([1,2,3,4,5], i => i%2 !== 0 ? [i] : [])

ES6 Réduire:

[1,2,3,4,5].map(i => i%2 !== 0 ? [i] : []).reduce( (a,b) => a.concat(b), [] )

4voto

JLRishe Points 22173

Un assez concis approche est de rendre l'utilisation de l' Array#concat.apply:

const flatMap = (arr, f) => [].concat.apply([], arr.map(f))

console.log(flatMap([1, 2, 3], el => [el, el * el]));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X