developer tip

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

optionbox 2020. 12. 29. 07:00
반응형

자바 스크립트에 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, [])

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

const xs = [1,2,3]

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


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 spread를 사용하는 약간의 짧은 방법이지만 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 provides a flatmap function, which to me is practically equivalent to Javascript providing it natively. If you're not a Lodash user, then ES6's Array.reduce() method can give you the same result, but you have to map-then-flatten in discrete steps.

Below is an example of each method, mapping a list of integers and returning only the odds.

Lodash:

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

ES6 Reduce:

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

I did somthing like this:

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]


One fairly concise approach is to make use of the Array#concat.apply:

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

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


We now have a flatMap() in Javascript! And it is supported pretty well

The flatMap() method first maps each element using a mapping function, then flattens the result into a new array. It is identical to a map() followed by a flat() of depth 1

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

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

ReferenceURL : https://stackoverflow.com/questions/39837678/why-no-array-prototype-flatmap-in-javascript

반응형