Daily-Interview-Question
Daily-Interview-Question copied to clipboard
第 36 题:使用迭代的方式实现 flatten 函数
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));
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]
迭代的实现:
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]), [])
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)))
使用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]
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;
}
/** *
- @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), []) }
ES10
arr.flat(Infinity);
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
}
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);
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();
const flatten = x => x.reduce((pre, cur) => Array.isArray(cur) ? pre.concat(flatten(cur)) : pre.concat(cur), []);
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
arr.toString().split(',')
or
arr.join(',').split(',')
function flatten(a) { return Array.isArray(a) ? [].concat(...a.map(flatten)) : a; }
为什么我老是喜欢投机取巧,哈哈
var arr = [1,[2,3,[4,5]],8]
function flat (arr) {
return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']')
}
flat(arr)
const flatten = (arr) => {
if(Array.isArray(arr)) {
return arr.reduce(((res, cur) => res.concat(flatten(cur))), [])
}else {
return [arr]
}
}
为什么我老是喜欢投机取巧,哈哈
var arr = [1,[2,3,[4,5]],8] function flat (arr) { return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '') + ']') } flat(arr)
虽然不是考点,但也没啥不好的。😂
为什么我老是喜欢投机取巧,哈哈
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));
var arr = [1,[2,3,[4,5]],8]
function flatten(arr) {
return arr.toString().split(",")
}
flatten(arr)
["1", "2", "3", "4", "5", "8"]
这样呢?
题目要求的是迭代的方式,各位取巧的同学。。。
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;
}
为什么我老是喜欢投机取巧,哈哈
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)
// 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
}
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()
}
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))
function flatten(arr, temp = []){
arr.forEach((item) => {
if(Array.isArray(item)) {
flatten(item, temp)
} else {
temp.push(item)
}
})
return temp
}
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;
}
function flatten(arr,result){ for(let item of arr){ if(Array.isArray(item)){ ...flatten(item,result) }else{ result.push(item) } } }
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)
// 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))
function flatten (arr) {
if (arr.length <=1) return arr;
const flatArr = [];
for (let i = 0; i<arr.length; i++) {
if(Object.prototype.toString.call(arr[i]) == '[object Array]') {
flatArr = flatArr.concat(flatten(arr[i]))
} else {
flatArr.push(arr[i])
}
}
return flatArr
}
let test = [[[1,2,3], 4], 5]
console.log(flatten(test))
迭代
const flatten = (arr, list = []) => {
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
arr = arr.slice(0, i).concat(arr[i]).concat(arr.slice(i + 1))
i--
} else {
list.push(arr[i])
}
}
return list
}
递归
const flat = (arr, list = []) => {
if (!Array.isArray(arr)) return list.push(arr)
arr.forEach(item => flat(item, list))
return list
}
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), []);
}
flattenDeep(arr1);
//我的最"笨"的迭代方法
function flat_arr(arr,new_arr){
for(let i=0;i<arr.length;i++){
let item=arr[i];
if(Array.isArray(item)){
flat_arr(item,new_arr);
}else{
new_arr.push(item)
}
}
}
var arr=[1,2,3,[4,5],[6,[7,[8]]]]
var new_arr=[];
flat_arr(arr,new_arr)
console.log(new_arr)
ES6的flat
函数
var arr=[1,2,3,[4,5],[6,[7,[8]]]]
arr.flat(Infinity);
迭代的实现:
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]), [])
很棒的思路,Array.some那句有点冗余,可以这样写 const flatten = function (arr) { while (arr.some(Array.isArray)) { arr = [].concat(...arr) } return arr }
迭代的实现:
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]), [])
使用 some 判断 怎么会一遍一遍把 arr 扩展吗?有谁可以解释下吗?
function flattern(arr) {
var result = []
arr.forEach(item => {
result = Array.isArray(item) ? result.concat(flattern(item)) :result.concat(item)
})
return result
}
function flatten(arr){
return arr.reduce(function(pre, cur){
if(Array.isArray(cur)){
return pre.concat(flatten(cur))
} else {
return pre.concat(cur)
}
}, [])
}
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
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();
}
flatten(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
一行代码:
const flatten = arr => arr.some(item => Array.isArray(item)) ? flatten([].concat(...arr)) : arr;
const flatten = arr => arr.reduce((acc, cur) => (Array.isArray(cur) ? [...acc, ...flatten(cur)] : [...acc, cur]), []);
function flatten(arr) {
var res = arr;
var i = 0;
while (i < res.length) {
if (Array.isArray(res[i])) {
res.splice(i, 1, ...res[i]);
}
i++;
}
console.log(res);
return res;
}
flatten([1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, [13, 14, [15, 16]]]]]);
不断迭代,遇到数组的元素,用该数组的解构替换该元素,这样就改变了原数组的长度,继续迭代,进行这种判断和处理。
const flatten = Function.apply.bind([].concat,[])
迭代的实现:
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]), [])
牛逼啊,老哥
递归写法
function flatten(arr) {
let result = []
for(let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]))
} else {
result.push(arr[i])
}
}
return result
}
toString 「存在限制,对于存在多种类型的数组无法使用」
因为元素的数组都是数字 多层数组直接调用 toString
会返回一个扁平的逗号分隔的字符串
[1,[2,[3,4]]].toString() // "1,2,3,4"
所以我们通过先转化成扁平字符串在转化为数字数组实现扁平化
function flatten(arr) {
return arr.toString().split(',').map(item => +item)
}
reduce
使用数组的reduce累加方法
function flatten(arr) {
return arr.reduce((prev, next) => {
return prev.concat(Array.isArray(next) ? flatten(next) : next)
}, [])
}
ES6扩展运算符
扩展运算符可以取出参数对象的可遍历属性,拷贝到当前对象之中
var arr = [1, [2, [3, 4]]];
console.log([].concat(...arr)); // [1, 2, [3, 4]]
但一次扩展运算符只能展开一层 我们可以添加循环条件
function flatten(arr) {
while(arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr)
}
return arr
}
同时我们可以设置出展开特定层数的方法
function flatten(arr, count) {
while (arr.some(item => Array.isArray(item) && count-- > 0)) {
arr = [].concat(...arr)
}
return arr
}
Generator函数
我们可以使用Generator函数来展开多重数组
function *flatten(arr) {
for(const item of arr) {
if (Array.isArray(item)) {
yield *flatten(item)
} else {
yield item
}
}
}
const flattened = [...flatten([1,2,[3,4,[5,6]]])]; // [1,2,3,4,5,6]
1. array.reduce
function flattenDeep(ary) {
return Array.isArray(ary) ? ary.reduce((a,b) => [...a,...flattenDeep(b)],[]) : [ary];
}
2. generator
function* demo(ary) {
for (let i = 0; i < ary.length; i++) {
if (Array.isArray(ary[i])) {
yield* demo(ary[i]);
} else {
yield ary[i];
}
}
}
for (let f of demo(ary)) {
console.log(f);
}
1.使用栈的思想实现 flat 函数
const flat = (arr) => { const stack = [...arr]; const res = []; while( stack.length ){ const next = stack.pop(); if(Array.isArray(next)){ stack.push(...next); } else { res.push(next) } } return res.reverse(); };
2.reduce + 递归
const flat = (arr) => { return arr.reduce((prv,cur) => { return Array.isArray(cur) ? prv.concat(flat(cur)) : prv.concat(cur) },[]) }
function flatten(arr) {
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
arr = arr.concat(arr[i])
arr.splice(i, 1)
}
}
return arr;
}
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
console.log(flatten(arr))
let test = [1, 2, [3, 4, 5,[6,7]]]; Array.prototype.myFlat = function () { const result = []; this.forEach(item => { if ((typeof item) !== 'object') { result.push(item); } else { result.push(...Array.prototype.myFlat.apply(item)); } }); return result; }; console.log(test.myFlat());
Array.reduce()
// 数组调用recduce方法时,可以传递两个参数,第一个参数为回调函数,第二个参数为一个初始值。
// 回调函数中需要传递两个参数,第一个参数为每次执行函数的返回值,第二个参数为当前索引对应数组的值。
// reduce的第二个参数是可以省略的,省略的话,回调函数第一次调用的参数为数组的第一项和第二项的值,
// 如果没有省略,回调函数的第一个参数就是这个初始值。
function flatten (arr) {
return arr.reduce((prev, curr) => {
return Array.isArray(curr) ? [...prev, ...flatten(curr)] : [...prev, curr]
}, [])
}
栈的写法
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
function flat(arr) {
let stack = []
let newArr = []
stack.push(arr)
while (stack.length) {
let item = stack.pop()
if (item.length) {
for (let i = item.length-1; i >-1; i--) {
stack.push(item[i])
}
} else {
newArr.push(item)
}
}
return newArr
}
console.log(flat(arr));
var arr = [1,[2,3,[4,5]],8] function flatten(arr) { return arr.toString().split(",") } flatten(arr) ["1", "2", "3", "4", "5", "8"]
这样呢?
应该让元素保持number类型, flatten(arr).map(Number)
Iterator 版:
const getIterator = (iteratorable) => iteratorable[Symbol.iterator]()
const getDataType = (data) => Object.prototype.toString.call(data).slice(8,-1)
const isArray = (data) => getDataType(data) === 'Array'
const flatten = (arr,deep=1) => {
const flatArr = []
const iteratorFn = (array,dep) => {
const iterator = getIterator(array)
while(true){
const obj = iterator.next()
if(obj.done){
break;
}
if(isArray(obj.value)&&dep>0){
dep--
iteratorFn(obj.value, dep)
}else{
flatArr.push(obj.value)
}
}
}
iteratorFn(arr,deep)
return flatArr
}
const arr = [1 ,[ 2,3,[4,5,6,[7,8,9,10]]]]
test:
const arr = [1 ,[ 2,3,[4,5,6,[7,8,9,10]]]]
flatten(arr)
// [1, 2, 3, Array(4)]
flatten(arr,2)
// [1, 2, 3, 4, 5, 6, Array(4)]
flatten(arr,3)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
迭代的实现:
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 也属于迭代吧?
递归
var flatten = (arr) => arr.every(ele => ele?.constructor !== Array) ? arr : flatten([].concat(...arr))
function flat(arr) {
let ret = [];
arr.forEach(item => {
if (+item === item) {
ret.push(item);
} else {
ret = ret.concat(flat(item));
}
})
return ret;
}
队列方式:
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;
}
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))
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
}
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]
用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))
迭代实现
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), [])
}
String(arr).split(',').map(Number)
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;
}
三种方式
// 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
}
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
}
使用栈将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()
}
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], []);
惭愧这么个简单的功能居然写了快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))
``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;`
//应该是迭代次数较少,而且比较方便的方法 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; }
迭代的实现:
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]
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;
}
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));
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]
迭代啊,不要用递归。
迭代的实现:
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自身
存收到,谢谢!
从语义的角度,递归实现是否用forEach
更好,另reduce
实现:
function flatten(arr) {
return arr.reduce((acc, cur) => {
if(Array.isArray(cur)) {
acc.push(...flatten(cur))
} else {
acc.push(cur)
}
return acc
}, [])
}
从语义的角度,递归实现是否用
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
}, [])
}