我有一个嵌套数组的例子:
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
这是获取嵌套数组长度的函数:
Array.prototype.getLength = function() {
var sum = 0;
function getMultiLength(array) {
for (count = 0; count < array.length; count ++) {
sum ++;
if (!array[count].length) {
getMultiLength(array[count]);
}
}
}
getMultiLength(this.valueOf());
return sum;
};
我对结果的期望是12,但我得到的是无限循环:
testArray.getLength(); //infinite loop
任何人都知道为什么以及如何获得嵌套数组长度?
答案 0 :(得分:7)
您现有的代码失败,因为检查递归是向后的。如果长度非零,您想要递归。所以它应该是
if (array[count].length) getMultiLength(array[count]);
else sum++;
正如您的代码所代表的那样,即使getMultiLength
不数组,也会调用array[count]
(因为如果array[count]
不是数组,{{1}将是未定义的)。所以它会永远地继续递归。通过在调试器中单步执行代码,可以很容易地弄明白。
顺便说一下,你不需要length
。在这种情况下,这与this.valueOf()
相同。
但实际上,您可以通过消除不必要的内部函数并使用递归调用的返回值来简化代码:
this
有些人可能更喜欢使用Array.prototype.getLength = function() {
let sum = 0;
for (let count = 0; count < this.length; count ++) {
sum += this[count].length ? this[count].getLength() : 1;
}
return sum;
};
来写这个:
reduce
另一种解决方案是展平阵列,然后找到展平阵列的长度。在这里,我们使用generator创建一个易于阅读和理解的拼合器(ES6功能):
Array.prototype.getLength = function() {
return this.reduce((sum, elt) =>
sum + (elt.length ? elt.getLength() : 1), 0);
};
&#13;
function *flatten(array) {
for (elt of array)
if (Array.isArray(elt)) yield *flatten(elt);
else yield elt;
}
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
console.log(Array.from(flatten(testArray)).length);
或者,使用您自己喜欢的flatten
实现,例如此递归版本:
flatten
或在ES5中
function flatten(value) {
return Array.isArray(value) ? [].concat(...value.map(flatten)) ? value;
}
function flatten(value) {
return Object.prototype.toString.call(value) === '[object Array]' ?
[].concat.apply([], value.map(flatten)) :
value;
}
原型如果你坚持把它放在原型上,那么
Array
使用Object.defineProperty(Array.prototype, 'getLength', {
value() { return flatten(this).length; }
});
使此属性不可枚举,不可配置等。
答案 1 :(得分:0)
试试这个:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
var s = 1;
$.each(testArray, function(index, value){
s = s + $(this).length;
});
console.log(s);
答案 2 :(得分:0)
我使用递归调用来查找嵌套数组长度
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
var totalLen=0;
function length(arr){
for(var ele in arr){
if(Array.isArray(arr[ele])){
length(arr[ele])
}else{
totalLen++;
}
}
}
length(testArray);
console.log(totalLen); //o/p 12
此处未使用全局变量
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
var ArrayUtils=function(){
var totalLength=0;
function getNestedArrayLength(arr){
for(var ele in arr){
if(Array.isArray(arr[ele])){
getNestedArrayLength(arr[ele])
}else{
totalLength++;
}
}
}
function getLength(arr){
getNestedArrayLength(arr);
return totalLength;
}
return {
getLength:getLength
}
}
var aU=new ArrayUtils();
var length=aU.getLength(testArray);
console.log(length); //Op 12
答案 3 :(得分:0)
对嵌套数组进行递归调用以计算其非数组项:
var testArray = [1, 2, [3, 4, [5, 6], 7], 8, 9, [10, 11], 12];
Array.prototype.getLength = function () {
function getMultiLength(array) {
var sum = 0;
for (var count = 0; count < array.length; count++) {
if (Array.isArray(array[count])) {
sum += getMultiLength(array[count]);
} else {
sum++;
}
}
return sum;
}
return getMultiLength(this.valueOf());
};
alert(testArray.getLength());
&#13;
答案 4 :(得分:0)
我想贡献的两种方法;
<强>递归:强>
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
flat = a => a.reduce((p,c) => p.concat(Array.isArray(c) ? flat(c) : c),[]);
result = flat(testArray).length;
console.log(result);
&#13;
<强>游击:强>
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
result = JSON.stringify(testArray).match(/,/g).length+1;
console.log(result);
&#13;
答案 5 :(得分:0)
以上所有答案都很有帮助,只需添加另一个简单答案即可。希望以后对某人有用。
const getLength = arr => arr.flat(Infinity).length;
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
console.log(getLength(testArray));
我们在这里使用flat()
方法将数组展平为单个数组,然后计算其长度。请注意,我们将深度设为Infinity
是因为我们想一直深入并计算整个长度。
flat()方法使用所有子数组元素创建一个新数组 递归连接到指定深度。在我们的 情况下,我们将深度定义为无穷大
详细了解flat()
答案 6 :(得分:0)
[].concat.apply([[]], testArray).length
有关申请的信息,请参见:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
答案 7 :(得分:-1)
试试这个:
Array.prototype.getLength = function() {
var sum = 0;
function getMultiLength(array) {
for (var count = 0; count < array.length; count ++) {
sum ++;
if (array[count].length) {
getMultiLength(array[count]);
}
}
}
getMultiLength(this.valueOf());
return sum;
};
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
testArray.getLength()