[javascript] 자바 스크립트에 Array.prototype.flatMap이없는 이유는 무엇입니까?

flatMap컬렉션에서 매우 유용하지만 javascript는 Array.prototype.map. 왜?

수동으로 flatMap정의하지 않고도 쉽고 효율적인 방법으로 자바 스크립트에서 에뮬레이션하는 방법이 flatMap있습니까?



답변

업데이트 : Array.prototype.flatMap 네이티브 ECMAScript로가는 중입니다. 현재 4 단계에 있습니다.

많은 환경에서 널리 지원됩니다. 아래 스 니펫을 사용하여 브라우저에서 작동하는지 확인하십시오.

const data =
  [ 1, 2, 3, 4 ]

console.log(data.flatMap(x => Array(x).fill(x)))
// [ 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 ]


자바 스크립트에 Array.prototype.flatMap이없는 이유는 무엇입니까?

프로그래밍은 마술이 아니고 모든 언어에는 다른 모든 언어가 가지고있는 기능 / 기본 요소가 없기 때문입니다.

중요한 것은

JavaScript를 사용하면 직접 정의 할 수 있습니다.

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))

또는 두 루프를 하나로 축소하는 재 작성

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))

에서 원하는 경우 Array.prototype아무것도 당신을 막을 수 없습니다

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

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

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

const xs = [1, 2, 3]

console.log(xs.flatMap(x => [x-1, x, x+1]))
.as-console-wrapper { top: 0; max-height: 100% !important; }


답변

flatMapES2019 (ES10)의 일부로 TC39의 승인을 받았습니다. 다음과 같이 사용할 수 있습니다.

[1, 3].flatMap(x => [x, x + 1]) // > [1, 2, 3, 4]

다음은 메서드의 내 고유 구현입니다.

const flatMap = (f, arr) => arr.reduce((x, y) => [...x, ...f(y)], [])

flatMap의 MDN 기사


답변

직접 정의하고 싶지 않다고 말씀 하셨지만 이 구현 은 매우 사소한 정의입니다.

동일한 github 페이지에도 다음이 있습니다.

다음은 renaudtertrais와 비슷하지만 es6를 사용하고 프로토 타입에 추가하지 않고 es6 스프레드를 사용하는 약간의 짧은 방법입니다.

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

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

flatMap(arr, s)

이 중 하나가 도움이 될까요?

(@ftor 덕분에)이 후자의 “솔루션”은 정말 큰 (예 : 300k 요소) 배열에서 호출 될 경우 “최대 호출 스택 크기 초과”문제가 발생한다는 점에 유의해야합니다 a.


답변

Lodash 는 플랫 맵 기능을 제공하는데, 나에게는 자바 스크립트가 기본적으로 제공하는 것과 거의 동일합니다. Lodash 사용자가 아니라면 ES6의 Array.reduce()방법이 동일한 결과를 제공 할 수 있지만 별도의 단계로 매핑 한 다음 평면화해야합니다.

다음은 정수 목록을 매핑하고 배당률 만 반환하는 각 방법의 예입니다.

Lodash :

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

ES6 감소 :

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


답변

상당히 간결한 접근 방식 중 하나는 다음을 사용하는 것입니다 Array#concat.apply.

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

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


답변

나는 다음과 같은 일을했다.

Array.prototype.flatMap = function(selector){
  return this.reduce((prev, next) =>
    (/*first*/ selector(prev) || /*all after first*/ prev).concat(selector(next)))
}

[[1,2,3],[4,5,6],[7,8,9]].flatMap(i => i); //[1, 2, 3, 4, 5, 6, 7, 8, 9]

[{subarr:[1,2,3]},{subarr:[4,5,6]},{subarr:[7,8,9]}].flatMap(i => i.subarr); //[1, 2, 3, 4, 5, 6, 7, 8, 9]


답변

이제 flatMap()Javascript가 있습니다! 그리고 그것은 꽤 잘 지원됩니다

flatMap () 메서드는 먼저 매핑 함수를 사용하여 각 요소를 매핑 한 다음 결과를 새 배열로 평면화합니다. map () 뒤에 깊이 1의 flat ()이 오는 것과 동일합니다.

const dublicate = x => [x, x];

console.log([1, 2, 3].flatMap(dublicate))