如何在Javascript中获取嵌套数组的长度? [英] How to get nested array length in Javascript?

查看:92
本文介绍了如何在Javascript中获取嵌套数组的长度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个嵌套数组的例子:

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中获取嵌套数组的长度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆