问题描述
我有一个嵌套数组的例子:
I have an example of nested array:
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
这是我获取嵌套数组长度的功能:
Here is my function for getting nested array length:
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,但是我得到的是无限循环:
My expectation for result would be 12, but instead what I got is infinite loop:
testArray.getLength(); //infinite loop
有人知道为什么以及如何获得嵌套数组长度吗?
Anyone know why and how to get nested array length?
推荐答案
您的代码存在问题
您的现有代码失败,因为递归检查是向后的.如果长度为非零,则要递归.所以应该是
Problem with your code
Your existing code fails because the check for recursing is backward. You want to recurse if the length is non-zero. So it should be
if (array[count].length) getMultiLength(array[count]);
else sum++;
按照您的代码,即使array[count]
不是不是数组,也会调用getMultiLength
(因为如果array[count]
不是数组,则length
将是未定义的).因此它将永远循环递归.只需在调试器中单步执行代码,就很容易弄清楚.
As your code stands, getMultiLength
will be called even if array[count]
is not an array (because if array[count]
is not an array, length
will be undefined). So it will keep recursing forever. This would be pretty easy to figure out by just stepping through your code in the debugger.
顺便说一句,您不需要this.valueOf()
.在这种情况下,与this
相同.
By the way, you don't need this.valueOf()
. That is the same as this
in this case.
但是实际上,您可以通过消除不必要的内部函数并使用递归调用的返回值来简化代码:
But actually, you could streamline your code by eliminating the unnecessary inner function, and using the return value of the recursive calls:
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
来编写此代码:
Some people might prefer to write this using reduce
:
Array.prototype.getLength = function() {
return this.reduce((sum, elt) =>
sum + (elt.length ? elt.getLength() : 1), 0);
};
使用展平的另一种解决方案
另一种解决方案是展平数组,然后找到展平数组的长度.在这里,我们使用生成器来创建展平器真正易于阅读和理解(ES6功能):
Another solution using flattening
An alternative solution is to flatten the array, then find the length of the flattened array. Here we use a generator to create a flattener which is real easy to read and understand (ES6 feature):
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
实现,例如此递归版本:
Or, use your own favorite implementation of flatten
, such as this recursive version:
function flatten(value) {
return Array.isArray(value) ? [].concat(...value.map(flatten)) ? value;
}
或在ES5
function flatten(value) {
return Object.prototype.toString.call(value) === '[object Array]' ?
[].concat.apply([], value.map(flatten)) :
value;
}
将其放在Array
原型上
如果您坚持将其放在原型上,那么
Putting it on the Array
prototype
If you insist on putting this on the prototype, then
Object.defineProperty(Array.prototype, 'getLength', {
value() { return flatten(this).length; }
});
使用defineProperty
可以使此属性不可枚举,不可配置等.
Use defineProperty
to make this property non-enumerable, non-configurable etc.
这篇关于如何在Javascript中获取嵌套数组的长度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!