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; }
답변
flatMap
ES2019 (ES10)의 일부로 TC39의 승인을 받았습니다. 다음과 같이 사용할 수 있습니다.
[1, 3].flatMap(x => [x, x + 1]) // > [1, 2, 3, 4]
다음은 메서드의 내 고유 구현입니다.
const flatMap = (f, arr) => arr.reduce((x, y) => [...x, ...f(y)], [])
답변
직접 정의하고 싶지 않다고 말씀 하셨지만 이 구현 은 매우 사소한 정의입니다.
동일한 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]