无递归展平多个嵌套数组的数组-javascript
也许这是一个愚蠢的问题,但我无法意识到,在没有递归的情况下,是否有可能展平多维数组 我用递归编写了一个解决方案:无递归展平多个嵌套数组的数组-javascript,javascript,arrays,flatten,Javascript,Arrays,Flatten,也许这是一个愚蠢的问题,但我无法意识到,在没有递归的情况下,是否有可能展平多维数组 我用递归编写了一个解决方案: function transform (arr) { var result = []; arr.forEach(flatten) function flatten (el) { if (Array.isArray(el)) { return el.forEach(flatten); } return result.pus
function transform (arr) {
var result = [];
arr.forEach(flatten)
function flatten (el) {
if (Array.isArray(el)) {
return el.forEach(flatten);
}
return result.push(el);
}
return result;
}
要展平的阵列示例:
[1, {a: [2, 3]}, 4, [5, [6]], [[7], 8, 9], 10]
和执行:
var a = [1, {a: [2, 3]}, 4, [5, [6]], [[7], 8, 9], 10];
var r = transform(r);
console.log(r); // [1, {a: [2, 3]}, 4, 5, 6, 7, 8, 9, 10]
谢谢 您必须通过其他方式管理状态 在这里,我使用一个数组。它让我们能够跟踪我们在做什么的总体计划中所处的位置。我觉得我做这件事相当不吸引人,但工作已经完成了
function transform(arr){
var state = [];
var i = 0,
a = arr;
var result = [];
while(true){
var val = a[i];
if(Array.isArray(val)){
state.push({i: i, a: a});
a = val;
i = -1;
} else if (val !== undefined) {
result.push(val)
}
if(i++ >= a.length - 1){
if(state.length > 0)
{
var s = state.pop();
a = s.a;
i = s.i + 1;
} else {
break;
}
}
}
return result;
}
var a = [1, {a: [2, 3]}, 4, [5, [6]], [[7], 8, 9], 10];
console.log(a); // Chrome Outputs: [1, Object, 4, Array[2], Array[3], 10]
var r = transform(a);
console.log(r); // Chrome Outputs: [1, Object, 4, 5, 6, 7, 8, 9, 10]
您可以使用堆栈。发现嵌套数组时,只需将其替换为其项即可
函数展平(arr){
var结果=[];
var stack=arr,第一个;
while(stack.length>0){
第一个=堆栈[0];
if(Array.isArray(第一个)){
//将嵌套数组替换为其项
Array.prototype.splice.apply(堆栈[0,1].concat(第一个));
}否则{
结果:推(第一);
//删除第一项
叠层拼接(0,1);
}
}
返回结果;
}
这是一个使用两个阵列展平另一个阵列的方案
基本上,一个数组保留某个级别的计数,另一个数组保留对该级别的数组的引用
与其他两种解决方案相比,它的主要优点是只使用Array#push,而没有其他的数组变异方法
函数变换(数组){
var结果=[],
级别=0,
reference=[array],
计数器=[0];
而(级别>=0){
if(计数器[level]>=参考[level].length){
级别--;
继续;
}
if(Array.isArray(参考[级别][计数器[级别]])){
参考[级别+1]=参考[级别][计数器[级别]]
计数器[电平]+;
级别++;
计数器[电平]=0;
继续;
}
结果.推(参考[水平][计数器[水平]]);
计数器[电平]+;
}
返回结果;
}
变量a=[1,{a:[2,3]},4,[5,[6]],[7],8,9],10],
r=变换(a);
控制台日志(r)代码>我在采访中遇到了完全相同的问题,并提出了以下解决方案:
function flattenNonRecursion(arr) {
const res = arr.slice();
let i = 0;
while (i < res.length) {
if (Array.isArray(res[i])) {
res.splice(i, 1, ...res[i]);
}
else {
i++;
}
}
return res;
}
console.log(flattenNonRecursion([1, {a: [2, 3]}, 4, [5, [6]], [[7], 8, 9], 10]));
// [1, {a: [2, 3]}, 4, 5, 6, 7, 8, 9, 10]
函数非递归(arr){
常数res=阵列切片();
设i=0;
而(i
所以,主要的想法是,我们正在通过数组前进,如果我们遇到一个数组,我们将用它的内容替换它,并继续前进。。。这个解决方案的复杂性是O(n)。我已经将@Misha的解决方案简化了一点:
function flatten(array) {
var result = [];
var stack = array
var item;
while (stack.length) {
item = stack.shift();
if (Array.isArray(item)) [].unshift.apply(stack, item);
else result.push(item);
}
return result;
}
这里是O(N)解,其中N是平坦数组中的项数,而不改变输入数组
当我们使用堆栈时,使用pop和push对我来说似乎更自然。此解决方案不使用非常昂贵的拼接、取消移位、移位和其他就地阵列突变方法
使用ES6扩展运算符(不是必须的)可以替换为apply
function flat(input) {
const stack = [...input];
const res = [];
while (stack.length) {
// pop value from stack
const next = stack.pop();
if (Array.isArray(next)) {
// push back array items, won't modify the original input
stack.push(...next);
} else {
res.push(next);
}
}
return res.reverse();
}
我们可以使用JS数组方法来实现这一点,从2019年5月起,除IE之外的大多数浏览器都支持JS数组方法
语法
深度:可选
指定嵌套数组结构应展平的深度级别。默认值为1
展平嵌套数组
一级深度:
const arr1=[1,2,3,4]]
常数flattarr=arr1.flat()
console.log(flattarr)
//[1,2,3,4]
为什么不使用递归?@JoeEnos更多的是关于自我教育和好奇心。只使用数组很容易,但不包括对象sure@juvian这有多容易?使用[].concat.apply([],arr)代码>对多个嵌套不起作用:/vara=[1,4,5,6]]、[5,6]、[7]]、8,9,10];console.log(a.toString().split(‘,’)
第一个
用于什么?我建议您在else子句中只需要这一行:result.push(stack.splice(0,1)[0])
从堆栈中删除第一项并将其推送到结果数组中。干杯这个解决方案比公认的更干净,谢谢!我喜欢这种方法
var newArray = arr.flat([depth]);