-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Comments
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;
} |
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), []); |
|
function 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]
}
} |
虽然不是考点,但也没啥不好的。😂 |
[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;
} |
[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()
} |
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;
} |
|
|
// 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 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) {
} 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来实现
|
迭代实现 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) |
|
三种方式 // 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的处理,抛砖引玉吧
|
``function myflatten(arr, deep) {
|
//应该是迭代次数较少,而且比较方便的方法 |
卧槽concat居然有这功能,只写过拼数组,单个元素也能拼厉害了, [ ].concat(1,2,[3]) == [1,2,3] |
|
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]]]] |
迭代啊,不要用递归。 |
recude内调用flatten自身 |
存收到,谢谢!
|
从语义的角度,递归实现是否用 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
}, [])
} |
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); |
存收到,谢谢!
|
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] |
存收到,谢谢!
|
|
将一个多维数组拍平为一个一维数组
The text was updated successfully, but these errors were encountered: