高级前端
js
【Q228】如何实现一个 flatMap 函数 (头条)

如何实现一个 flatMap 函数 (头条)

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 229 (opens in a new tab)

Author 回答者: rex-ll (opens in a new tab)

没说不让用flat;所以有个取巧的办法 const flatMap = arr => arr.flat().map(_ => _);

Author 回答者: HuiFeiYa (opens in a new tab)

function flatMap(arr){
    let list = []
    arr.forEach(item=>{
        if(Array.isArray(item)){
            const l = flatMap(item)
            list.push(...l)
        }else{
            list.push(item)
        }
    })
    return list
}

Author 回答者: shfshanyue (opens in a new tab)

Array.prototype.flatMap 已经是 EcmaScript 的标准,看一个例子,它的输出是多少?

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

很可惜,不是 [2, 3, 4, 5],原因在于 flatMap 实际上是先 mapflat,实现如下

Array.prototype.flatMap = function (mapper) {
  return this.map(mapper).flat();
};

flat 可以如下实现

const flat = (list) => list.reduce((a, b) => a.concat(b), []);

Author 回答者: haotie1990 (opens in a new tab)

Array.prototype.FlatMap = function (callback, thisArgs) {
  return this.reduce((acc, value) => {
    return (acc = acc.concat(callback.call(thisArgs, value)));
  });
};

Author 回答者: 719676340 (opens in a new tab)

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat (opens in a new tab)

Author 回答者: QC2168 (opens in a new tab)

// 先map再flat
let myFlatMap = function (fn) {
  let target = this;
  return target.map((i) => fn(i)).flat();
};
Array.prototype.myFlatMap = myFlatMap;
let arr = ["it's Sunny in", "", "California"];
let arr1 = arr.map((x) => x.split(" "));
let arr2 = arr.flatMap((x) => x.split(" "));
let arr3 = arr.myFlatMap((x) => x.split(" "));
console.log(arr1); // [["it's","Sunny","in"],[""],["California"]]
console.log(arr2); // ["it's","Sunny","in", "", "California"]
console.log(arr3); // ["it's","Sunny","in", "", "California"]