Open YvetteLau opened 5 years ago
const deepFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v));
function flattenDeep(arr) {
if(!(arr instanceof Array)) {
throw 'Please pass in the array.'
}
// 使用map 函数判断每一个元素,如果是数组,递归返回一个一维数组,如果不是返回这个元素,最后通过 concat 方法把所有的一维数组合并,返回一维数组
return [].concat(...arr.map(x => Array.isArray(x) ? flattenDeep(x) :x))
}
var arr1 = [1, [2, [3, [4]], 5]];
var oneDim = flattenDeep(arr1)
console.log(oneDim); // [1,2,3,4,5]
const flattenDeep = (arr => {
let newArray = [];
return (arr, flag) => {
arr.forEach(element => {
if (element instanceof Array) {
flattenDeep(element, true);
} else {
newArray.push(element);
}
});
// 防止重复添加
let array = JSON.parse(JSON.stringify(newArray));
if (!flag) {
newArray = [];
return array;
}
};
})();
console.log(flattenDeep([1, [2, [3, [4]], 5]]));
const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]];
const flattenDeep = arr => {
const resArr = [];
while (arr.length > 0) {
const next = arr.pop();
if (Object.prototype.toString.call(next) === '[array Object]') {
arr.push(...next);
} else {
resArr.push(next);
};
};
return resArr.reverse();
};
const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]];
const flattenDeep = arr => arr.flat(Math.pow(2, 23) - 1);
function doSomething() {
let returnArr = [];
return function loop(arr) {
for(let t of arr){
if(!Array.isArray(t)){
returnArr.push(t);
}else{
returnArr.concat(loop(t));
}
}
return returnArr;
}
}
let loop = doSomething();
console.log(loop([1,[2,[3,[4,[5]]]]]));
以上
function flattenDeep(arr) {
return arr.reduce((acc, item) => Array.isArray(item) ? acc.concat(flattenDeep(item)) : acc.concat(item), []);
}
方法一
方法二 undefined会有问题
方法一 const flattenDeep = arr => { return arr.flat(Infinity); };
方法二
const flattenDeep = arr => { return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []); };
该方法可以用于简单数据处理,
const flattenDeep = (data) => data.toString().split(',').map(Number)
flattenDeep([1, [2, [3, [4]], 5]]) // [ 1, 2, 3, 4, 5 ]
暂未纳入标准,存在兼容问题,谨慎使用
const flattenDeep = (arr) => arr.flat(Infinity)
flattenDeep([1, [2, [3, [4]], 5]]) // [ 1, 2, 3, 4, 5 ]
const flattenDeep = (data) => {
let ret = []
data.forEach(item => {
if(Array.isArray(item)){
ret = ret.concat(flattenDeep(item))
} else {
ret.push(item)
}
})
return ret;
}
flattenDeep([1, [2, [3, [4]], 5]]) // [ 1, 2, 3, 4, 5 ]
const flattenDeep = (arr) => arr.reduce((cur,pre) => cur.concat(Array.isArray(pre) ? flattenDeep(pre) : pre), [])
flattenDeep([1, [2, [3, [4]], 5]]) // [ 1, 2, 3, 4, 5 ]
function flattenDeep(arr) {
let newArr = [];
let len = arr.length;
for (let i = 0; i < len; i++) {
if (Array.isArray(arr[i])) {
newArr = newArr.concat(flattenDeep(arr[i]));
} else {
newArr.push(arr[i]);
}
}
return newArr;
}
function flattenDeep(arr) {
[].concat(...arr.map(item => Array.isArray(item) ? flattenDeep(item) : item))
}
function flattenDeep(arr) {
arr.toString().split(',').map(item => +item)
}
但是此种方法只能正确转换纯数字数组,不能转换带字符串的数组。比如会将[1,'2','3',4]转换为数组[1,2,3,4]
function flatDeep(arry) {
let returnArray = [];
if (arry.length == 0) {
return [];
}
arry.forEach(item => {
if (Object.prototype.toString.call(item) == "[object Array]") {
returnArray = returnArray.concat(flatDeep(item));
} else {
returnArray.push(item);
}
});
return returnArray;
}
function flattenDeep2(arr) {
return arr.reduce((item, next) => {
return item.concat(
Array.isArray(next) ? flattenDeep2(next) : next
);
}, []);
}
function flattenDeep3(arr) {
return arr.toString().split(",");
}
缺点: 类型可能会丢失或者改变。
function flattenDeep(arr,result=[]){
if(arr.constructor !== Array || arr.length<=0)
return result;
for(const value of arr){
if(value && value.constructor === Array){
result=[...result,...flattenDeep(value)];
}else{
result.push(value);
}
}
return result;
}
function flatten(arr) { return arr.reduce((prev, next)=> { return prev.concat(Array.isArray(next) ? flatten(next) : next) }, []) }
采用递归的方式
function arrSet(arr) {
function mySet(a) {
if (Object.prototype.toString.call(a) === '[object Array]') {
const length = a.length
for (let i = 0; i < length; i++ ) {
mySet(a[i])
}
} else {
arr.push(a)
}
}
return mySet
}
arr 是结果存放的数组, a 是要扁平化的数组
toString 和 split
function arrSet(arr) {
return arr.toString().split.map(item => {
return Number(item)
})
}
join 和split
reduce
function arrSet(arr) {
return arr.reduce((result, item) => {
return result.concat(Array.isArray(item)?arrSet(item): item)
}, [])
}
方法一:Array.flat()
该方法默认只会“扁平”一层,传入Infinity
const flattenDeep = function (arr) {
if (!(arr instanceof Array)) {
throw '传入的参数不是数组!'
}
return arr.flat(Infinity)
}
方法二:递归
function flattenDeep(arr) {
if (!(arr instanceof Array)) {
throw '传入的参数不是数组!'
}
let flattedArr = []
arr.forEach(item => {
if (item instanceof Array) {
flattedArr = flattedArr.concat(flattenDeep(item))
} else {
flattedArr.push(item)
}
})
return flattedArr
}
方法三:将数组转成字符串,再通过split,分割成数组(缺陷:会造成原始数组中的元素类型发生改变)
const flattenDeep = arr => arr.toString().split(',')
方法四:reduce
const flattenDeep = arr => {
return arr.reduce((prev, cur) => {
return prev.concat(Array.isArray(cur) ? flattenDeep(cur) : cur)
}, [])
}
利用 Array.prototype.flat
function flattenDeep(arr, deepLength) {
return arr.flat(deepLength);
}
console.log(flattenDeep([1, [2, [3, [4]], 5]], 3));
利用 reduce 和 concat
function flattenDeep(arr){
return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
}
console.log(flattenDeep([1, [2, [3, [4]], 5]]));
使用 stack 无限反嵌套多层嵌套数组
function flatten(input) {
const stack = [...input];
const res = [];
while (stack.length) {
// 使用 pop 从 stack 中取出并移除值
const next = stack.pop();
if (Array.isArray(next)) {
// 使用 push 送回内层数组中的元素,不会改动原始输入 original input
stack.push(...next);
} else {
res.push(next);
}
}
// 使用 reverse 恢复原数组的顺序
return res.reverse();
}
console.log(flattenDeep([1, [2, [3, [4]], 5]]));
对于以上同学回答的一个总结:
ES6 Array.prototype.flat()
将数组扁平化在ES6中有一个方法flat()
,该方法返回一个新的数组,对原数组没有影响,但默认情况下只会展开一层。
如果不管是多少层都转换成以为数组,可以传递 Infinity
关键字作为参数。实现方法如下:
function flattenDeep(arr){
return arr.flat(Infinity);
}
Array.prototype.concat() & Array.prototype.map() & [...]
map()
函数是对每一个元素进行处理,判断当前元素如果为数组则使用递归,调用函数进行转换,最终完成所有元素的检测
var flattenDeep = function fn(arr) {
return [].concat(...arr.map(value => Array.isArray(value) ? fn(value) : value));
}
这里有一个需要注意的地方是,经过处理的元素如果是数组,处理后返回的仍为数组,需要使用借助于扩展运算符...
Array.prototype.concat() & Array.prototype.reduce()
reduce()
是将数组所有的元素从左到右计算成一个值返回,返回的是新的数组,对原数组没有影响。如果当前元素为数组,则可以使用递归,一步一步完成数组的转换
var flattenDeep = function fn(arr) {
return arr.reduce((a1, a2) => Array.isArray(a2) ? a1.concat(fn(a2)) : a1.concat(a2), [])
}
第一种方法更简单方便理解,但涉及到兼容性的问题,最后一种方法在理解上稍微吃力且使用了递归但胜在兼容多版本浏览器。
toString()
方法的过程中会将数组内元素的数据类型改变,或者转换失败的情况。
var flattenDeep = function fn(arr) {
return arr.toString().split(',');
}
虽然出现下列数组的几率不大,但仍需要注意其转换对数据产生的影响。
// 使用前三种方法都没有问题,数据类型没有发生改变
// 使用最后一种,数据有丢失以及类型发生改变的情况
var arr = [1, '1', [null, 'null', [undefined, 'undefined', NaN, ['NaN']], {'a': 2}]];
Array.prototype.flat
[1, [2, [3, [4]], 5, [6]]].flat(Infinity)
递归
const flattenDeep = (function() { let newArr = []; return function loop(array) { if (!(array instanceof Array)) return array; let len = array.length; if (len === 0) return array; array.forEach((item, index) => { if (item instanceof Array) { loop(item); } else { newArr.push(item); } }); return newArr; }; })(); let arr = [1, [2, [3, [4]], 5, [6]]]; let newArr = flattenDeep(arr); console.log(newArr);
//1.使用toString()和split(',')方法 function flattenDeep(item){ if(Array.isArray(item)){ var fn1=item.toString().split(',').map(item=>{ return Number(item) }) console.log("toString()+split()",fn1) } } flattenDeep(a)
//2.回调函数
function flatten(arr){
var res = [];
for(var i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
res = res.concat(flatten(arr[i]))
}else{
res.push(arr[i])
}
}
return res
}
console.log('回调函数',flatten(a))
//3.reduce()和concat()
function deepFlatten2 (arr){
return [].concat(...arr.map(x => Array.isArray(x) ? deepFlatten2(x) :x))
}
var oneDim = deepFlatten2(a)
console.log("concat()",oneDim);
//4.flat
function flattenDeep3(arr,deepLength){
return arr.flat(Infinity)
}
console.log('flat',flattenDeep3(a))
参照上面【Sakura-pgh】大佬和【Aruthor】闭包的写法,整理一下: 第一种:递归方式
const deepFlatten = arr => Array.from(
new Set([].concat(
...arr.map(
v => Array.isArray(v) ? deepFlatten(v) : v
)
)
)
);
var arr = [1, 4, 6, [3,6,9,10,1,[3,6,1]]];
console.log(deepFlatten(arr));
第二种:递归方式
const deepArray = (arr) => {
let list = [];
arr.forEach((item, index) => {
if(Array.isArray(item)){
list = list.concat(deepArray(item));
}else{
list.push(item);
}
})
return Array.from(new Set(list));
}
}
var arr = [1, 4, 6, [3,6,9,10,1,[3,6,1]]];
console.log(deepArray(arr));
//1,递归
function flattenDeep(arr){
let deepArr = []
arr.forEach(element => {
if(Array.isArray(element)){
deepArr = deepArr.concat(flattenDeep(element))
}else{
deepArr.push(element)
}
});
return deepArr
}
console.log(flattenDeep([1,[2,3,[4,5]]])) //[ 1, 2, 3, 4, 5 ]
//2,map方法
function flattenDeep2(arr){
//map方法确保得到的是一维数组。cancat可以合并一维数组
return [].concat(arr.map(item => Array.isArray(item) ? flattenDeep2(item) : item))
}
console.log(flattenDeep([1,[2,3,[4,5],7],[2,3]]))
var arr = [1, [2, 3], [4, [7, 9]], { name: "kk", age: [23, 32] }];
// 一 递归方法
function _flattenDeep(arr) {
var newArr = [];
if (Array.isArray(arr)) {
arr.forEach(item => {
Array.isArray(item) ? newArr = newArr.concat(_flattenDeep(item)) : newArr.push(item);
})
} else {
return "false"
}
return newArr;
}
console.log(_flattenDeep(arr));
// 利用 Array.prototype.flat函数
function flattenDeep(arr, deepLength) {
return arr.flat(deepLength);
}
console.log(flattenDeep(arr, 3));
flat 详解:https://blog.csdn.net/qq_29055201/article/details/86530254
递归实现
var arr = [1,2,3,4,[5,6],7,8]
funcion getFlat(list){
var newArr =[]
if list===[] return false
list.forEach(function(item){
Array.isArray(item)? newArr = newArr.concat(getFlat(item)): newArr = newArr.push(item)
})
return newArr;
}
getFlat(arr)
flat实现
var arr = [1,2,3,4,5,[1,2,3,[4,5,6]]]
function flattenDeep(list,length){
return list.flat(length)
}
flattenDeep(arr,3)
var arr1=[1,2,3,[1,2,3,4,[2,3,4]]];
function flattenDeep(arr1) {
return arr1.reduce((acc,val)=>Array.isArray(val)?acc.concat(flattenDeep(val)):acc.concat(val),[]);
}
console.log(flattenDeep(arr1));
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
function flatten(input) {
const stack=[...input];
const res=[];
while (stack.length) {
const next=stack.pop();
if(Array.isArray(next)){
console.log(...next);
stack.push(...next);
}else{
res.push(next);
}
}
return res.reverse();
}
console.log(flatten(arr1));
转载自MDN: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
function flatter(arr){ var result =[]; for(var i=0;i<arr.length;i++){ if(arr.isArray(arr[i])){ result = result.concat(flatter(arr[i])) }else{ result.push(arr[i])]} } function flattenDeep(arr){ return arr.reduce(function(pre,cur){ if(arr.isArray(pre){ return cur.concat(flatter(pre))}) }else{ return cur.concat(pre)},[] ) }
实现如下:
function isArray (array) {
return typeof array === 'object' && array instanceof Array
}
var result = []
function flatternDeep(array) {
if (!isArray(array)) {
return array
}
// 本质上仍旧是需要递归来解决
array.forEach(arrayItem => {
if (isArray(arrayItem)) {
flatternDeep(arrayItem)
} else {
result.push(arrayItem)
}
})
}
综合 各位大佬
function flattenDeep(arr, deepLength) {
return arr.flat(deepLength);
}
console.log(flattenDeep([1, [2, [3, [4]], 5]], 3));
function flattenDeep(arr){
return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
}
console.log(flattenDeep([1, [2, [3, [4]], 5]]));
function flatten(input) {
const stack = [...input];
const res = [];
while (stack.length) {
// 使用 pop 从 stack 中取出并移除值
const next = stack.pop();
if (Array.isArray(next)) {
// 使用 push 送回内层数组中的元素,不会改动原始输入 original input
stack.push(...next);
} else {
res.push(next);
}
}
// 使用 reverse 恢复原数组的顺序
return res.reverse();
}
console.log(flattenDeep([1, [2, [3, [4]], 5]]));
原生js
const flatDeep = arr =>[].concat(...arr.map(v => Array.isArray(v) ? flatDeep(v) : v));
const arr = [1,2,3,4,5,6,7,[8,9,10,[11,12,13]]];
console.log(flatDeep(arr));
运用flat方法
const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12]]]];
const flattenDeep = arr => arr.flat(4);
console.log(flattenDeep(arr));
reduce方法
const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, 12,[13]]]]];
const flattenDeep = (arr) => arr.reduce((cur,pre) => cur.concat(Array.isArray(pre) ? flattenDeep(pre) : pre), [])
console.log(flattenDeep(arr));
如: