Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 36 题:使用迭代的方式实现 flatten 函数 #54

Open
Moriarty02 opened this issue Mar 19, 2019 · 83 comments
Open

第 36 题:使用迭代的方式实现 flatten 函数 #54

Moriarty02 opened this issue Mar 19, 2019 · 83 comments

Comments

@Moriarty02
Copy link

var arr=[1,2,3,[4,5],[6,[7,[8]]]]
/**
 * 使用递归的方式处理
 * wrap内保存结果ret 
 * 返回一个递归函数
 *
 * @returns
 */
function wrap(){
    var ret=[];
    return function flat(a){
        for(var item of a){
            if(item.constructor===Array){
                ret.concat(flat(item))
            }else{
                ret.push(item)
            }
        }
        return ret
    }
}
console.log(wrap()(arr));

将一个多维数组拍平为一个一维数组

@suguoyao
Copy link

const spreadableSymbol = Symbol.isConcatSpreadable
const isFlattenable = (value) => {
  return Array.isArray(value) || (typeof value == 'object' && value !== null
    && Object.prototype.toString.call(value) === '[object Arguments]') ||
    !!(spreadableSymbol && value && value[spreadableSymbol])
}

/**
 * flatten的基本实现,具体可以参考lodash库的flatten源码
 * @param array 需要展开的数组
 * @param depth 展开深度
 * @param predicate 迭代时需要调用的函数
 * @param isStrict 限制通过`predicate`函数检查的值
 * @param result 初始结果值
 * @returns {Array} 返回展开后的数组
 */
function flatten(array, depth, predicate, isStrict, result) {
  predicate || (predicate = isFlattenable)
  result || (result = [])

  if (array == null) {
    return result
  }

  for (const value of array) {
    if (depth > 0 && predicate(value)) {
      if (depth > 1) {
        flatten(value, depth - 1, predicate, isStrict, result)
      } else {
        result.push(...value)
      }
    } else if (!isStrict) {
      result[result.length] = value
    }
  }
  return result
}

flatten([1, 2, 3, [4, 5, [6]]], 2)
// [1, 2, 3, 4, 5, 6]

@yeyan1996
Copy link

迭代的实现:

let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]

const flatten = function (arr) {
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr)
    }
    return arr
}

console.log(flatten(arr))

递归的实现(ES6简写):

const flatten = array => array.reduce((acc, cur) => (Array.isArray(cur) ? [...acc, ...flatten(cur)] : [...acc, cur]), [])

@Rashomon511
Copy link

Rashomon511 commented Mar 19, 2019

let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]

迭代实现

    function flatten(arr) {
      let arrs =[...arr]
      let newArr = [];
      while (arrs.length){
        let item = arrs.shift()
        if(Array.isArray(item)){
          arrs.unshift(...item)
        }else {
          newArr.push(item)
        }
      }
      return newArr
    }

递归实现

    function flatten(arr) {
    let arrs = [];
      arr.map(item => {
        if(Array.isArray(item)){
          arrs.push(... flatten(item))
        } else {
          arrs.push(item)
        }
      })
      return arrs
    }

字符串转换

arr.join(',').split(',').map(item => Number(item)))

@underlineMY
Copy link

使用Generator实现数组flatten:

function* flat(arr){
	for(let item of arr){
		if(Array.isArray(item)){
			yield* flat(item);//Generator委托
		}else {
			yield item
		}
	}
}
function flatten(arr) {
	let result = [];
	for(let val of(flat(arr))){
		result.push(val);
	}
	return result;
}
let arr1 = [1,[2,3,[4,5],6],[7]];
console.log(flatten(arr1));//[1, 2, 3, 4, 5, 6, 7]

@Ray-56
Copy link

Ray-56 commented Mar 19, 2019

const arr = [1,2,3,[4,5],6,[7,[8, 9, 10]]]

// 递归
function flatten(arr, res = []) {
    for (let i = 0; i < arr.length; i++) {
        if (typeof arr[i] === 'object') {
            flatten(arr[i], res);
        } else {
            res.push(arr[i]);
        }
    }
    return res;
}

// 队列
function flatten1(arr) {
    const newArr = [...arr];
    const res = [];
    while (newArr.length) {
        const item = newArr.shift(); // 出队
        if (Array.isArray(item)) {
            newArr.unshift(...item); // 入队
        } else {
            res.push(item);
        }
    }
    return res;
}

@fingerpan
Copy link

/**
*

  • @param {Array} arr 需要扁平化的数组
  • @param {Number} [depth=1] 扁平化深度
  • @return {Array} 扁平化后的新数组
    */
    function flatten(arr, depth = 1) {
    return arr.reduce((newArr, nextArr) => newArr.concat(depth > 1 && Array.isArray(nextArr) ? flatten(nextArr, depth - 1) : nextArr), [])
    }

@ringcrl
Copy link

ringcrl commented Mar 19, 2019

ES10

arr.flat(Infinity);

@wind-stone
Copy link

function flatten(arr) {
  const result = [...arr];
  for (let i = 0; i < result.length; i++) {
    const item = result[i]
    if (Array.isArray(item)) {
      Array.prototype.splice.apply(result, [i, 1, ...item])
      i--
    }
  }
  return result
}

@gaomin
Copy link

gaomin commented Mar 20, 2019

var arr=[1,2,3,[4,5],[6,[7,[8]]]]
function flatten(arr, result){
    if(!result){
        var result = [];
    }
    
    if(Object.prototype.toString.call(arr) == "[object Array]"){
        for (let i=0; i<arr.length; i++){
            if(Object.prototype.toString.call(arr[i]) == "[object Array]"){
                flatten(arr[i], result);
            }else{
                result.push(arr[i]);
            }
        } 
    }
    return result;
}

flatten(arr);

@dorseysen
Copy link

dorseysen commented Mar 20, 2019

const flatten = (arr, deep) => {

    deep = deep ? deep : Infinity;
    while(deep && arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr);
        deep --;
    }
    return arr;
}
Array.prototype.flatten = function (deep) {
    
    return flatten(this, deep);
}
[1,[123,["213",["dorsey","123"]]]].flatten();

@wind1996
Copy link

const flatten = x => x.reduce((pre, cur) => Array.isArray(cur) ? pre.concat(flatten(cur)) : pre.concat(cur), []);

@xiaobaichiliangpi
Copy link

xiaobaichiliangpi commented Mar 26, 2019

let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
arr.toString().split(',')
or
arr.join(',').split(',')

@scq000
Copy link

scq000 commented Mar 27, 2019

function flatten(a) {
return Array.isArray(a) ? [].concat(...a.map(flatten)) : a;
}

@z253573760
Copy link

z253573760 commented Mar 29, 2019

image

@formattedzzz
Copy link

为什么我老是喜欢投机取巧,哈哈

var arr = [1,[2,3,[4,5]],8]
function flat (arr) {
  return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']')
}
flat(arr)

@cheqianxiao
Copy link

const flatten = (arr) => {     
  if(Array.isArray(arr)) {
    return arr.reduce(((res, cur) => res.concat(flatten(cur))), [])
  }else {
    return [arr]
  }
}

@yu910709
Copy link

yu910709 commented Apr 3, 2019

为什么我老是喜欢投机取巧,哈哈

var arr = [1,[2,3,[4,5]],8]
function flat (arr) {
  return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']')
}
flat(arr)

虽然不是考点,但也没啥不好的。😂

@dorseysen
Copy link

dorseysen commented Apr 3, 2019

为什么我老是喜欢投机取巧,哈哈

var arr = [1,[2,3,[4,5]],8]
function flat (arr) {
  return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']')
}
flat(arr)

虽然不是考点,但也没啥不好的。😂

这个怎么样😂

[1,[2,3,[4,5]],8].join(',').split(',').map(item => Number(item));

@qinnnn
Copy link

qinnnn commented Apr 9, 2019

var arr = [1,[2,3,[4,5]],8]
function flatten(arr) {
   return arr.toString().split(",")
}
flatten(arr)
 ["1", "2", "3", "4", "5", "8"]

这样呢?

@goodwinfame
Copy link

题目要求的是迭代的方式,各位取巧的同学。。。

function flatten(arr){
	let des = [];
	for(let i in arr){
		const v = arr[i];
		if(Array.isArray(v)){
			des = [...des,...flatten(v)]
			
		} else {
			des.push(v);
			
		}


	}
	return des;
	
}
function flatten(arr){
	let des = [...arr], i = 0;
	while(i <= des.length - 1) {
		if(Array.isArray(des[i])){
			des = [...des.slice(0, i), ...des[i], ...des.slice(i + 1, des.length)]
		} else {
			i++;
		}	
	}
	return des;
}

@cliYao
Copy link

cliYao commented Apr 17, 2019

为什么我老是喜欢投机取巧,哈哈

var arr = [1,[2,3,[4,5]],8]
function flat (arr) {
  return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']')
}
flat(arr)

虽然不是考点,但也没啥不好的。😂

这个怎么样😂

[1,[2,3,[4,5]],8].join(',').split(',').map(item => Number(item));

[1,[2,3,[4,5]],8].toString().split(",").map(Number)

@LoneYin
Copy link

LoneYin commented Apr 24, 2019

// reduce
function flatten(arr) {
    return arr.reduce((total, item) => total.concat(Array.isArray(item) ? flatten(item) : [item]), [])
}
// map
function flatten(arr) {
    return [].concat(...arr.map(item => Array.isArray(item) ? flatten(item) : item))
}
// for
function flatten(arr, result = []) {
    for (let item of arr) {
        if (Array.isArray(item)) {
            flatten(item, result)
        } else {
            result.push(item)
        }
    }
    return result
}

@waningflow
Copy link

function flattern(list) {
  const stack = [...list]
  const des = []
  while (stack.length) {
    const next = stack.pop()
    if (Array.isArray(next)) {
      stack.push(...next)
    } else {
      des.push(next)
    }
  }
  return des.reverse()
}

@liuyanxing
Copy link

var arr=[1,2,3,[4,5],[6,[7,[8]]]]
/**
 * 使用递归的方式处理
 * wrap内保存结果ret 
 * 返回一个递归函数
 *
 * @returns
 */
function wrap(){
    var ret=[];
    return function flat(a){
        for(var item of a){
            if(item.constructor===Array){
                ret.concat(flat(item))
            }else{
                ret.push(item)
            }
        }
        return ret
    }
}
console.log(wrap()(arr));

将一个多维数组拍平为一个一维数组

ret = ret.concat(flat(item))

@Arrogant128
Copy link

Arrogant128 commented Jul 16, 2019

function flatten(arr, temp = []){
  arr.forEach((item) => {
   if(Array.isArray(item)) {
    flatten(item, temp)
   } else {
    temp.push(item)
   }
  })
  return temp
}

@AsakuraC
Copy link

function flatten(arr) {
  if (!Array.isArray(arr) || !arr.length) return [];
  
  const tempArr = []; // 辅助数组
  const result = []; // 用来保存结果

  tempArr.push([arr, 0]);

  while (tempArr.length) {
    const currentArr = tempArr[tempArr.length - 1];
    const [current, index] = currentArr;

    if (index >= current.length) {
      tempArr.pop();
      continue;
    }

    currentArr[1]++; // 下标 + 1

    const currentItem = current[index];
    if (Array.isArray(currentItem)) {
      tempArr.push([currentItem, 0]);
      continue;
    }

    result.push(currentItem);
  }

  return result;
}

@snowzijun
Copy link

snowzijun commented Jul 16, 2019

function flatten(arr,result){ for(let item of arr){ if(Array.isArray(item)){ ...flatten(item,result) }else{ result.push(item) } } }

@NANAYWY
Copy link

NANAYWY commented Jul 19, 2019

let attr=[1,2,3,[4,5],[6,[7,[8]]]];
   function flatten(attr){
     if(Array.isArray(attr)){
       let att=[]
        for (let item of attr){
          att=  att.concat(flatten(item))
        }
        return att
     }
     else {
       return attr
     }
   }
flatten (attr)

@soc221b
Copy link

soc221b commented Jul 22, 2019

// O(n)
const flat = function(array) {
  let tail = []
  let index = 0
  while (0 < array.length) {
    let elem = array.pop()
    if (Array.isArray(elem)) {
      array.push(...elem)
    } else {
      tail.push(elem)
    }
  }
  return tail.reverse()
}

const nestedArray = [[[1,2],3,[4,[5,6]],7,8],9]
console.log(nestedArray)
console.log(flat(nestedArray))

@tjwyz
Copy link

tjwyz commented Jul 27, 2020

function flat(arr) {
	let ret = [];
	arr.forEach(item => {
		if (+item === item) {
			ret.push(item);
		} else {
			ret = ret.concat(flat(item));
		}
	})
	return ret;
}

@gitwillsky
Copy link

队列方式:

function flatten(arr) {
  const ret = [];
  const queue = [];
  let index = 0;

  while (index < arr.length || queue.length) {
    // 取出 queue中的元素然后处理
    const queueLen = queue.length;
    for (let i = 0; i < queueLen; i++) {
      const item = queue.shift();
      if (Array.isArray(item)) {
        for (let j = 0; j < item.length; j++) {
          queue.push(item[j]);
        }
      } else {
        ret.push(item);
      }
    }
    // 取出原数组放入queue
    if (index < arr.length) queue.push(arr[index++]);
  }
  return ret;
}

@cc8476
Copy link

cc8476 commented Aug 23, 2020

var arr=[1,2,3,[4,5],[6,[7,[8]]]]

function getArr(arr) {

let result=[]

for (let i = 0; i < arr.length; i++) {
    const element = arr[i];
    if(element instanceof Array) {
       result = [...result,...getArr(element)]
    }
    else {
        result.push(element)
    }
}
return result;

}

console.log(getArr(arr))

@wabRul
Copy link

wabRul commented Sep 4, 2020

function flatten(arr) {
  if (!arr.length) {
    return []
  }
  let stack = [...arr]
  let res = []
  while (stack.length) {
    let item = stack.pop()
    if (Array.isArray(item)) {
      for (let cld of item) {
        stack.push(cld)
      }
    } else {
      res.unshift(item)
    }
  }
  return res
}

@79percent
Copy link

var arr=[1,2,3,[4,5],[6,[7,[8]]]];
function flatten(arr = []){
    const newArr = [];
    while(arr.length > 0){
        const first = arr.shift();
        if(Array.isArray(first)){
            arr = [...first, ...arr];
        }else {
            newArr.push(first);
        }
    }
    return newArr;
}
console.log(flatten(arr));//  [1, 2, 3, 4, 5, 6, 7, 8]

@JeremyChenn
Copy link

JeremyChenn commented Jan 6, 2021

用reduce来实现

let a= [[1,2,[3]],[4,5,[6,[[7],8]],9]]
const flatten = (arr) => {
    return arr.reduce((pre, item) => {
        return pre.concat(Array.isArray(item) ? flatten(item) : item)
    },[])
}
console.log(flatten(a))

@pan-Z2l0aHVi
Copy link

迭代实现

function flatten(arr) {
  const result = []
  let target = arr

  while (Array.isArray(target)) {
    const copy = target.slice()
    for (let i = 0; i < copy.length; i += 1) {
      target = copy[i]
      if (!Array.isArray(copy[i])) {
        result.push(copy[i])
      }
    }
  }
  return result
}

递归实现

function flatten(arr) {
  return arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? flatten(cur) : cur), [])
}

@koujialong
Copy link

String(arr).split(',').map(Number)

@miyukoarc
Copy link

miyukoarc commented Mar 10, 2021

const a = [1,2,3,[4,5,6,[7,8]]]

// 递归
const flatten = (arr) => {
  return arr.reduce((sum,curr) => {
    return sum.concat(Array.isArray(curr) ? flatten(curr) : curr);
  },[])
}

// 迭代
const iterativeFlatten = (arr) => {
  const stack = [];
  const rlt = [];
  stack.push(arr);
  while(stack.length){
    while(Array.isArray(stack[stack.length - 1])){
      const temp = stack.pop();
      for(let i = temp.length-1; i>=0; i++){
        stack.push(temp[i]);
      }
    }
    rlt.push(stack.pop());
  }
  return rlt;
}

@MrLeihe
Copy link

MrLeihe commented Apr 24, 2021

三种方式

//  toString()
var flatten = (arr) => {
  return arr.toString().split(',').map(Number)
}

// 递归
var flatten = (arr) => {
  var ret = []
  arr.forEach(item => {
    var temp = Array.isArray(item) ? flatten(item) : [item]
    ret.push(...temp)
  })
  return ret
} 

// 迭代
var flatten = (arr) => {
  if(!arr.length) {
    return []
  }

  var ret = []
  var queue = [arr]
  while(queue.length) {
    var cur = queue.shift()
    if (Array.isArray(cur)) {
      queue.unshift(...cur)
    } else {
      ret.push(cur)
    }
  }
  
  return ret
} 

@ruanlinxin
Copy link

function flatten(arr) {
    const items = [].concat(arr) // 拷贝数组防止直接操作原数组
    const res = [] // 创建新的数组
    while (items.length) { // 如果拷贝的数组还有数据
        const item = items.shift() // 弹出第一个数据
        if (Array.isArray(item)) { // 如果弹出的是一个数组
            items.unshift(...item) // 那么推入
        } else { 
            res.push(item) // 推入返回的数组
        }
    }
    return res
}

@lee88688
Copy link

lee88688 commented May 6, 2021

使用栈将element反复推入拍平数组

let flatten = arr => {
    const newArr = [];
    let cur = null;
    while(cur = arr.pop()) {
        if (Array.isArray(cur)) {
            arr.push(...cur)
        } else {
            newArr.push(cur)
        }
    }
    return newArr.reverse()
}

@sunnala
Copy link

sunnala commented Jun 2, 2021

ES6实现无限层级的flatten

const flatten = arr => arr.reduce((acc, cur) => (
    Array.isArray(cur) 
   ? [...acc, ...flatten(cur)]
   : [...acc, cur]
), []);

进一步优化一下,带有depth参数

const flattenBydepth = (arr, depth = 1) => 
    depth > 1
        ? arr.reduce((acc, cur) => Array.isArray(cur) 
            ? [...acc, ...flattenBydepth(cur, depth -1)] 
            : [...acc, cur], [])
        : arr.reduce((acc, cur) => [...acc, cur], []);

@mygod48
Copy link

mygod48 commented Oct 26, 2021

惭愧这么个简单的功能居然写了快50行。。。不过带上了对depth的处理,抛砖引玉吧

const iterationFlatten = (arr,depth=1)=>{
    if (!Array.isArray(arr)) {
        return [];
    }

    if (depth <= 0) {
        depth = 1;
    }

    // 存放结果
    const result = [];
    // 当前迭代深度
    let currentDepth = 0;
    // 对应深度中,当前进行迭代的索引(因为能够进行迭代的必然是数组)
    const layerIterationIndex = [0];
    // 对应深度中,当前正在进行迭代的数组对象
    let targetStack = new Array();

    targetStack.push(arr);

    while (layerIterationIndex[0] !== arr.length) {
        // 本次迭代的元素所在的数组
        const layerElement = targetStack[currentDepth];
        // 本次迭代的元素 
        const target = layerElement[layerIterationIndex[currentDepth]];
        // 本层迭代是否应该继续(数组已经迭代完毕,或者当前深度超出depth指定的值)
        const endOfThisLayer = (layerIterationIndex[currentDepth] === (layerElement.length)) || (currentDepth > depth);

        if (endOfThisLayer) {
            // 如果超出depth指定的值,则将本层元素直接放进结果            
            if (currentDepth > depth) {
                result.push(layerElement);
            }

            // 层数-1 上层迭代索引+1(因为上一层迭代中,本元素已经迭代完毕)
            currentDepth--;
            layerIterationIndex[currentDepth]++;
            
            // 弹出本层迭代元素,以及迭代索引
            layerIterationIndex.pop();
            targetStack.pop();
        } else {
            // 如果本次迭代的元素是数组,则以本元素进行深一层迭代,将本此迭代元素入栈,迭代索引入栈,初始化为0
            if (Array.isArray(target)) {
                targetStack.push(target);
                currentDepth++;
                layerIterationIndex.push(0);
            } else {
                // 如果不是数组,则直接放入结果数组,并且本层迭代索引+1
                result.push(target);
                layerIterationIndex[currentDepth]++;
            }
        }
    }

    return result;
}

// (5) [1, 2, 3, 4, Array(3)]
console.log(iterationFlatten([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]))
// (7) [1, 2, 3, 4, 5, 6, Array(3)]
console.log(iterationFlatten([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]], 2))
// (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(iterationFlatten([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]], Infinity))

@gagadGG
Copy link

gagadGG commented Oct 29, 2021

``function myflatten(arr, deep) {
let result = [];
let temp1 = arr;//当前用来遍历的数组
let temp2 = [];//保存下一次用来遍历的数组

    while (deep) {
        //如果元素是数组就放到temp2里面去,不是就放到result里
        for (let i = 0; i < temp1.length; i++) {
            if (temp1[i] instanceof Array) {
                temp2.push(...temp1[i]);
            } else {
                result.push(temp1[i]);
            }
        }
        deep--;
        //到达深度后要把没遍历的数组放到result里
        if (deep == 0) {
            result.push(...temp2);
        } else {
        temp1 = temp2;
        temp2 = [];
    }
}
return result;`

@kingforever
Copy link

kingforever commented Nov 6, 2021

//应该是迭代次数较少,而且比较方便的方法
function flatten(arr) {
if(!(arr instanceof Array)){
return
}
var result = [], temp = [],head;
if(arr.length <= 0) {
return result;
}
temp.push(arr);
while (temp.length) {
head = temp.shift();
//元素是数组
if (head instanceof Array) {
for (let i = 0; i < head.length; i++) {
if (!(head[i] instanceof Array)) {
result.push(head[i]);
} else {
temp.push(head[i])
}
}
} else {
result.push(head)
}
}
return result;
}

@yaoocheng
Copy link

迭代的实现:

let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]

const flatten = function (arr) {
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr)
    }
    return arr
}

console.log(flatten(arr))

递归的实现(ES6简写):

const flatten = array => array.reduce((acc, cur) => (Array.isArray(cur) ? [...acc, ...flatten(cur)] : [...acc, cur]), [])

卧槽concat居然有这功能,只写过拼数组,单个元素也能拼厉害了, [ ].concat(1,2,[3]) == [1,2,3]

@chiic
Copy link

chiic commented Nov 23, 2021

function flatten(arr) {
    let i = 0;
    while(i < arr.length) {
        if(Array.isArray(arr[i])) {
            var len = arr[i].length;
            arr.splice(i, 1, ...arr[i]);
        } else {
            i++;
        }
    }
    return arr;
}

@Four-Names
Copy link

function flat(target) {
  let arr = [];
  target.forEach((element) => {
    if (Array.isArray(element)) arr.push(...flat(element));
    else arr.push(element);
  });
  return arr;
}
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]];
console.log("结果", flat(arr));

@dongwei200079
Copy link

var arr=[1,2,3,[4,5],[6,[7,[8]]]]
function flatten(arr){
return arr.reduce((pre,cur)=>{
return pre.concat(Array.isArray(cur)?flatten(cur):cur)
},[])
}
var newArr = flatten(arr)
console.log(newArr) // [1,2,3,4,5,6,7,8]

@jianxing-xu
Copy link

迭代啊,不要用递归。

@Yuweiai
Copy link

Yuweiai commented Jul 13, 2022

迭代的实现:

let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]

const flatten = function (arr) {
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr)
    }
    return arr
}

console.log(flatten(arr))

递归的实现(ES6简写):

const flatten = array => array.reduce((acc, cur) => (Array.isArray(cur) ? [...acc, ...flatten(cur)] : [...acc, cur]), [])

使用 reduce 也属于迭代吧?

recude内调用flatten自身

@kingforever
Copy link

kingforever commented Jul 13, 2022 via email

@Yuweiai
Copy link

Yuweiai commented Jul 13, 2022

从语义的角度,递归实现是否用forEach更好,另reduce实现:

function flatten(arr) {
  return arr.reduce((acc, cur) => {
    if(Array.isArray(cur)) {
      acc.push(...flatten(cur))
    } else {
      acc.push(cur)
    }

    return acc
  }, [])
}

@Yuweiai
Copy link

Yuweiai commented Jul 13, 2022

从语义的角度,递归实现是否用forEach更好,另reduce实现:

function flatten(arr) {
  return arr.reduce((acc, cur) => {
    if(Array.isArray(cur)) {
      acc.push(...flatten(cur))
    } else {
      acc.push(cur)
    }

    return acc
  }, [])
}
// 返回数组的维数(虽然没用到)
function arrDimension(arr) {
  return arr.length ? Math.max(...arr.map(item => Array.isArray(item) ? arrDimension(item) + 1 : 1)) : 1
}

function flatten(arr, depth = 1) {
  if(depth === 0) return arr

  return arr.reduce((acc, cur) => {
    if(Array.isArray(cur)) {
      acc.push(...flatten(cur, depth - 1))
    } else {
      acc.push(cur)
    }

    return acc
  }, [])
}

@benzhemin
Copy link

benzhemin commented Feb 19, 2023

const flattenRecursion = (itemList, resList) => {
    itemList.forEach(item => {
        if (Array.isArray(item)) {
            flattenFormat(item, resList);
            return;
        }

        resList.push(item);
    })

    return resList;
}

const flattenIterate = itemList => {
    const flattenedList = [];

    while(itemList.length > 0) {
        let head = itemList.shift();
        if (Array.isArray(head)) {
            itemList.unshift(...head);
        } else {
            flattenedList.push(head);
        }
    }

    return flattenedList;
}



const arr = [1,2,3,[4,5],[6,[7,[8]]]];

const flattenedList = flattenIterate(arr, []);
console.log(flattenedList);

@kingforever
Copy link

kingforever commented Feb 19, 2023 via email

@G-WangZH
Copy link

function reduceFlat(arr = []) {
  return arr.reduce((res, item) => res.concat(Array.isArray(item) ? reduceFlat(item) : item), [])
}
reduceFlat([1,2,3,[4,5],[6,[7,[8]]]])
// [1, 2, 3, 4, 5, 6, 7, 8]

@kingforever
Copy link

kingforever commented Sep 20, 2023 via email

@XW666
Copy link

XW666 commented Sep 22, 2023

const flatten2 = (arr) => {
    let list = []
    //递归方式
    let fun = (data) => {
      for (let c of data) {
        if (Array.isArray(c)) {
          fun(c)
        } else {
          list.push(c)
        }
      }
    }
    fun(arr)
    console.log('flatten2', list)
  }
  flatten2([1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests