flat
Array.prototype.flat
扁平化 多维数组 -> 一维数组
const arr = [0, 1, [2, 3], 4, 5];
const newArr = arr.flat();
console.log(newArr);//[0, 1, 2, 3, 4, 5]
返回一个新的数组
将二维数组转化为一维数组
const arr = [0, 1, [2, 3], 4, 5];
const newArr = arr.flat();
console.log(arr === newArr);//false
flat默认情况下参数是1 -> 向内深入一层
const arr = [0, 1, [2, [3, 4], 5], 6];
const newArr = arr.flat();
console.log(newArr);
参数
结构深度
默认为1 向数组内部深入一层 变成两层
flat默认情况下是浅的扁平化
参数 正无穷 Infinity 结构深度无穷大的设置
const arr = [0, [1, 2, [3, 4, [5, 6, [7, 8, [9]]]]]];
const newArr = arr.flat(Infinity);
console.log(newArr);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
当参数为负数的时候 不做任何扁平化处理
const arr = [0, 1, [2, [3, 4], 5], 6];
const newArr = arr.flat(-2);
console.log(newArr);
字母字符串也不做处理
const arr = [0, 1, [2, [3, 4], 5], 6];
const newArr = arr.flat('a');
console.log(newArr);
数字字符串 -> Number -> 数字类型
const arr = [0, 1, [2, [3, 4], 5], 6];
const newArr = arr.flat('2');
console.log(newArr);//[0, 1, 2, 3, 4, 5, 6]
当为0时 也不做任何处理
const arr = [0, 1, [2, [3, 4], 5], 6];
const newArr = arr.flat(0);
console.log(newArr);
true / fasle 都要经过Number转化为数字类型在处理
对于稀松数组
剔除所有的数组空隙empty
const arr = [1, , [2, , [3, 4, , 5, , , 6, [7, , , 8, 9, , [0]]]]];
const newArr = arr.flat(Infinity);
console.log(newArr);
浅扁平化实现
concat 是可以放入多个数组元素或者其他数组
var a = 1,
b = [2, 3],
c = [3, 4];
const newArr = b.concat(a, c);
console.log(newArr);//[2, 3, 1, 3, 4]
1.用reduce实现
function shallowFlat(arr) {
return arr.reduce(function (prev, current) {
return prev.concat(current);
}, []);
}
2.ES6展开运算符
function shallowFlat(arr) {
return [].concat(...arr);
}
深扁平化
reduce + concat + isArray + 递归
Array.prototype.deepFlat = function () {
var arr = this,
deep = arguments[0] !== Infinity ? arguments[0] >>> 0 : Infinity;
return deep > 0
? arr.reduce(function (prev, current) {
return prev.concat(Array.isArray(current) ? current.deepFlat(deep - 1) : current);
}, [])
: arr;
};
forEach + isArray + push + 递归
Array.prototype.deepFlat = function () {
var arr = this,
deep = arguments[0] !== Infinity ? arguments[0] >>> 0 : Infinity,
res = [];
(function _() {
arr.forEach(function (item) {
if (Array.isArray(item) && deep > 0) {
_(item, deep - 1);
} else {
res.push(item);
}
});
})(arr, deep);
return res;
};
for of + isArray + push 去掉empty
Array.prototype.deepFlat = function(){
var arr = this,
deep = arguments[0] !== Infinity ? arguments[0] >>> 0 : Infinity,
res = [];
(function _(arr,deep){
for(var item of arr){
if(Array.isArray(item) && deep > 0){
_(item,deep - 1)
}else{
//判断是否时empty 用void 0
item !== void 0 && res.push(item)
}
}
})(arr,deep)
return res
}
用栈 + 展开运算符 vue 用过的方法
Array.prototype.deepFlat = function () {
var arr = this,
stack = [...arr],
res = [];
while (stack.length) {
const popItem = stack.pop();
console.log(stack);
if (Array.isArray(popItem)) {
stack.push(...popItem);
} else {
popItem !== void 0 && res.push(popItem);
}
}
return res.reverse();
};
纯递归
Array.prototype.deepFlat = function () {
var arr = this,
res = [];
(function _(arr) {
arr.forEach(function (item) {
if (Array.isArray(item)) {
_(item);
} else {
res.push(item);
}
});
})(arr);
return res;
};
生成器函数
function* deepFlat(arr) {
for (var item of arr) {
if (Array.isArray(item)) {
yield* deepFlat(item);
} else {
yield item;
}
}
}
数组扁平化后数组去重并升序排列
原始写法
var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
function flatten(arr) {
var _arr = arr || [],
fArr = [],
len = _arr.length,
item;
for (var i = 0; i < len; i++) {
item = _arr[i];
if (_isArr(item)) {
fArr = fArr.concat(flatten(item));
} else {
fArr.push(item);
}
}
return fArr;
function _isArr(item) {
return {}.toString.call(item) === '[object Array]';
}
}
console.log(flatten(arr));// [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]
挂载到原型上
Array.prototype.flatten = function () {
var _arr = this,
toStr = {}.toString;
if (toStr.call(_arr) !== '[object Array]') {
throw new Error('只有数组才能调用flatten方法');
}
var fArr = [];
return _arr.reduce(function (prev, item) {
return prev.concat(toStr.call(item) === '[object Array]' ? item.flatten() : item);
}, []);
};
console.log(arr.flatten());
Array.prototype.flatten = function () {
var _arr = this,
toStr = {}.toString;
if (toStr.call(_arr) !== '[object Array]') {
throw new Error('只有数组才能调用flatten方法');
}
var fArr = [];
_arr.forEach(function (item) {
toStr.call(item) === '[object Array]'
? (fArr = fArr.concat(item.flatten()))
: fArr.push(item);
});
return fArr;
};
console.log(arr.flatten());
ES6 箭头函数写法
const flatten = (arr) =>
arr.reduce((prev, item) => {
return prev.concat({}.toString.call(item) === '[object Array]' ? flatten(item) : item);
}, []);
console.log(flatten(arr));
flatMap
Array.prototype.flatMap
flat + map
遍历 + 扁平化
const arr = ['123', '456', '789'];
const newArr = arr.flatMap(function (item) {
return item.split('');
});
console.log(newArr);
返回一个新的数组
const arr = ['123', '456', '789'];
const newArr = arr.flatMap(function (item) {
return item.split('');
});
console.log(newArr === arr); //false
回调参数
当前遍历的元素 当前遍历元素在数组中对应的下标 数组本身
const arr = ['123', '456', '789'];
const newArr = arr.flatMap(function (item, index, arr) {
console.log(item, index, arr);
});
回调中this默认指向window
const arr = ['123', '456', '789'];
const newArr = arr.flatMap(function (item, index, arr) {
console.log(this);
});
严格模式下 this为undefined
'use strict';
const arr = ['123', '456', '789'];
const newArr = arr.flatMap(function (item, index, arr) {
console.log(this);
});
第二个参数
改变回调内this的指向
const arr = ['123', '456', '789'];
const newArr = arr.flatMap(
function (item, index, arr) {
console.log(this);
},
{ a: 1 }
);
实例
对字符串进行分段处理 并生成新的数组
const arr = ["My name's kobe", "I'm 35", 'years old.'];
const newArr = arr.flatMap(function (item) {
return item.split(' ');
});
console.log(newArr);
对数组进行遍历的过程中进行某些运算 并添加回数组中
const arr = [1, -2, -3, 5, 8, -9, 6, 7, 0];
const newArr = arr.flatMap(function (item, index) {
if (item < 0 && index >= 1) {
return [item, `${item} + ${arr[index - 1]} = ${item + arr[index - 1]}`];
}
return item;
});
console.log(newArr);
重写myFlatMap
Array.prototype.myFlatMap = function () {
if (typeof cb !== 'function') {
throw new TypeError('Callback must be a function');
}
var arr = this,
arg2 = arguments[1],
res = [];
for (var i = 0; i < arr.length; i++) {
item = cb.apply(arg2, [arr[i], i, arr]);
item && res.push(item);
}
return res.flat();
};