flatMap컬렉션에서 매우 유용하지만 javascript는 Array.prototype.map. 왜?
수동으로 flatMap정의하지 않고도 쉽고 효율적인 방법으로 자바 스크립트에서 에뮬레이션하는 방법이 flatMap있습니까?
flatMap컬렉션에서 매우 유용하지만 javascript는 Array.prototype.map. 왜?
수동으로 flatMap정의하지 않고도 쉽고 효율적인 방법으로 자바 스크립트에서 에뮬레이션하는 방법이 flatMap있습니까?
arr.map(...).reduce(...)).
답변:
업데이트 : 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; }
Array.prototype._mylib_flatMap:) 에 네임 스페이스를 지정하는 것이 더 나은 것으로 간주 되거나 단순히를 정의하는 대신 ES6 기호를 사용하는 것이 더 좋습니다 Array.prototype.flatMap.
map. 전역 함수 로 정의 된 함수 코드를 상상해보세요 ! 두 번째는 나쁜 관행입니다
append, map, filter, foldl, foldr디폴트의 이름 공간에서 수많은 다른 사람의 사이에서. 누군가 "글로벌이 나쁘다"또는 "네이티브를 확장하는 것은 나쁘다"라고 말하는 것을 들었 기 때문에 나쁜 습관이 아닙니다. 라켓은 가장 잘 설계된 언어 중 하나입니다. 당신은 그것을 적절하게 어떻게 / 언제 해야할지 모릅니다.
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)], [])
flapMap? 나는 내지도를 평평하게 만들고 싶다.
const flatMap = (arr, ...args) => [].concat(...arr.map(...args));(또는 apply스프레드 연산자를 사용할 수없는 경우 사용)-이 concat 버전에는 솔루션 하위에 언급 된대로 거대한 배열에 대한 호출 스택 크기 문제가 있지만
직접 정의하고 싶지 않다고 말씀 하셨지만 이 구현 은 매우 사소한 정의입니다.
동일한 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.
[].concat(...(new Array(300000).fill("foo").map(x => x.toUpperCase()))). 물론입니다. 코너 케이스입니다. 하지만 적어도 언급해야합니다.
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.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]
{ "message": "Uncaught TypeError: [1,2,3].flatMap is not a function", "filename": "https://stacksnippets.net/js", "lineno": 15, "colno": 23 }
Array.prototype.flatMap()이제 JS에 도착했습니다. 그러나 모든 브라우저가 Mozilla 웹 문서 에서 현재 브라우저 호환성을 확인하는 것을 지원하는 것은 아닙니다 .
어떤 flatMap()방법을 수행하는 첫 번째 후 새로운 배열 결과 (요소가 평평하게되기 때문에, 2 차원 배열되어 이제도 1d) 병합, 인수 콜백 함수를 사용하여 각 원소를 매핑한다.
다음은 함수 사용 방법의 예입니다.
let arr = [[2], [4], [6], [8]]
let newArr = arr.flatMap(x => [x * 2]);
console.log(newArr);
arr.reduce((arr, v) => (arr.push(...v), arr), [])?