我想将N维数组拼成单个数组。该数组只有数字,但每个元素本身不一定是数组。样本数据: (md =多维)fiddle
var mdArray = [1,2,[3, 4], [[[5, 6, 7]]]];
Array.prototype.flattenAll = function () {
var self = this,
//finds elements that are not arrays
numbers = $.grep(self, function (n, i) {
return !$.isArray(n);
}),
//gets md arrays
nestedArrays = $.grep(self, function (n, i) {
return $.isArray(n);
}),
returnArray = [];
nestedArrays = $.map(nestedArrays, function (a, ix) {
return a.flatten();
});
return returnArray.concat(numbers).concat(nestedArrays);
};
Array.prototype.flatten = function () {
return this.reduce(function (a, b) {
return a.concat(b);
});
}
flatten函数适用于简单的数组数组,但不适用于秩为>的数组。这似乎是一个简单的递归修复,但我没有看到它。在没有更多阵列变平的情况下,我在这里错过了什么才能让flatten
运行?
答案 0 :(得分:2)
一个非常简单的循环可以解决这个问题:
Array.prototype.flattenAll = function () {
var flattened = this.slice();
for (var i=0; i<flattened.length; )
if ($.isArray(flattened[i]))
flattened.splice.apply(flattened, [i, 1].concat(flattened[i]));
else
i++;
return flattened;
}
答案 1 :(得分:2)
您可以使用Array.prototype.reduce
:
Array.prototype.flatten = function (){
return this.reduce(function(c,x){
return Array.isArray(x) ? c.concat(x.flatten()) : c.concat(x);
}, []);
}
顺便说一句,如果你要修改核心对象原型(比如Array.prototype
),你应该至少使用Object.defineProperty
,这样你的函数就不可枚举了:
Object.defineProperty(Array.prototype, 'flatten', {
value: function (){
return this.reduce(function(c,x){
return Array.isArray(x) ? c.concat(x.flatten()) : c.concat(x);
}, []);
},
enumerable: false
});
如果您想了解为什么不使用Object.defineProperty
这是一个坏主意,请尝试以下操作:
Array.prototype.foo = function(){};
console.log([1,2,3]);
您将在Chrome中看到的是:
[1, 2, 3, foo: function]
可能不是任何人想要看到的......使用Object.defineProperty
并将enumerable
设置为false
可以防止这种情况发生。
其他浏览器的控制台日志不太友好。但是如果你想要一个可以在任何浏览器中使用的铁板示例,请执行以下操作:
Array.prototype.foo = function(){};
for(var x in [1,2,3]) console.log(x):
答案 2 :(得分:2)
你可以用漂亮的递归来做到这一点:
function flatten(array, i) {
i = ~~i;
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 :(得分:1)
var mdArray = [1,2,[3, 4], [[[5, 6, 7]]]];
function flatten(mdArray){
var data = [];
$.each(mdArray,function(index,item){
if(typeof(item) != 'object'){
data.push(item);
}else{
data = data.concat(flatten(item));
}
});
return data;
}
var result = flatten(mdArray);
console.log(result);
答案 4 :(得分:0)
function flattenArrayOfArrays(a, r){
if(!r){ r = []}
for(var i=0; i<a.length; i++){
if(a[i].constructor == Array){
flattenArrayOfArrays(a[i], r);
}else{
r.push(a[i]);
}
}
return r;
}
答案 5 :(得分:0)
var mdArray = [1,2,[3, 4], [[[5, 6, 7]]]];
console.log(_.flatten(mdArray)); // Outputs [1, 2, 3, 4, 5, 6, 7]
答案 6 :(得分:0)
这是针对此问题的Vanilla JavaScript解决方案
var _items = {'keyOne': 'valueOne', 'keyTwo': 'valueTwo', 'keyThree': ['valueTree', {'keyFour': ['valueFour', 'valueFive']}]};
// another example
// _items = ['valueOne', 'valueTwo', {'keyThree': ['valueTree', {'keyFour': ['valueFour', 'valueFive']}]}];
// another example
/*_items = {"data": [{
"rating": "0",
"title": "The Killing Kind",
"author": "John Connolly",
"type": "Book",
"asin": "0340771224",
"tags": "",
"review": "i still haven't had time to read this one..."
}, {
"rating": "0",
"title": "The Third Secret",
"author": "Steve Berry",
"type": "Book",
"asin": "0340899263",
"tags": "",
"review": "need to find time to read this book"
}]};*/
function flatten() {
var results = [],
arrayFlatten;
arrayFlatten = function arrayFlattenClosure(items) {
var key;
for (key in items) {
if ('object' === typeof items[key]) {
arrayFlatten(items[key]);
} else {
results.push(items[key]);
}
}
};
arrayFlatten(_items);
return results;
}
console.log(flatten());
&#13;