我无法弄清楚为什么我的代码没有按照指示展平嵌套数组。我非常感谢这里的一些帮助。我使用递归来获取嵌套数组的实际值。我试图调试我的代码,似乎每次递归都会替换我的结果数组。
//Helper methods
function toType(obj){
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
function each(collection, callback){
if (Array.isArray(collection)){
for (var i = 0; i < collection.length; i++){
callback(collection[i], i, collection)
}
} else {
for (var i in collection){
callback(collection[i], i, collection)
}
}
}
//Flatten function
function flatten(array, isShallow=false, callback){
var results = [];
each(array, function(item){
if (!!isShallow && toType(item) === 'array'){
each (item, function(value){
results.push(value);
})
} else if (toType(item) !== 'array'){
results.push(item);
} else {
return flatten(item)
}
})
return results;
}
flatten([1, [2], [3, [[4]]]]);
// ---> [1]
答案 0 :(得分:2)
您的问题似乎与此行有关:
return flatten(item)
返回此处是一个问题,因为循环将结束,结果中的当前条目将被忽略,以及其余项目。该行应更改为添加
的结果flatten(item)
通过推送到结果数组。
我建议使用库来做这类事情。 http://underscorejs.org/#flatten是一个很棒的人!
答案 1 :(得分:1)
请参阅下面的重构代码。
主要的变化是,我们不是创建results
的新副本,而是将其传递给后续调用以作为参考。
请参阅添加的评论
//Helper methods
function toType(obj){
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
function each(collection, callback){
if (Array.isArray(collection)){
for (var i = 0; i < collection.length; i++){
callback(collection[i], i, collection)
}
} else if(typeof collection === 'object'){
//type number was failing here
for (var i in collection){
callback(collection[i], i, collection)
}
}
else {
//default for primitive types
callback(collection, 0, collection);
}
}
//Flatten function
//Removed isShallow, how do we know if its shallow or not?
//Added results as arg, so we only manipulate the reference to results
//And to not create multiple scopes of var results;
function flatten(array, results, callback){
results = results || [];
each(array, function(item){
//removed 3rd if clause not needed.
//Only need to know if item is an object or array
if (toType(item) === 'array' || toType(item) === 'object'){
each (item, function(value){
flatten(value,results);
})
} else {
results.push(item);
}
})
return results;
}
var array1 = [1,[2,[3,4]]];
var array2 = [5,[6,[7,[8, {a:9,b:[10,11,12]}]]]];
var obj = {a:array1, b:array2};
console.log(flatten(array1)); // [ 1, 2, 3, 4 ]
console.log(flatten(array2)); // [ 5, 6, 7, 8, 9, 10, 11, 12 ]
console.log(flatten(obj)); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ]
答案 2 :(得分:0)
你可以这样做:
function flatten(array, i) {
i = i || 0;
if(i >= array.length)
return array;
if(Array.isArray(array[i])) {
return flatten(array.slice(0,i)
.concat(array[i], array.slice(i+1)), i);
}
return flatten(array, i+1);
}
示例:强>
var weirdArray = [[],1,2,3,[4,5,6,[7,8,9,[10,11,[12,[[[[[13],[[[[14]]]]]]]]]]]]]
flatten(weirdArray);
//returns ==> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
答案 3 :(得分:0)
在javascript中展平数组的最好方法是使用Array的拼接功能。请遵循以下代码。它也适用于嵌套。
function flattenArray(arr){
for(var i=0;i<arr.length;i++){
if(arr[i] instanceof Array){
Array.prototype.splice.apply(arr,[i,1].concat(arr[i]))
}
}
return arr;
}
答案 4 :(得分:-1)
使用underscore.js的展平函数(http://underscorejs.org/#flatten)。 Underscore.js是一个第三方库,具有80多个奇怪的功能,使您作为javascript程序员的生活更轻松。不要重新发明轮子。
var _ = require('underscore');
_.flatten([1, [2], [3, [[4]]]]);
=> [1, 2, 3, 4];