Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
嵌套列表的Javascript长度_Javascript_Arrays - Fatal编程技术网

嵌套列表的Javascript长度

嵌套列表的Javascript长度,javascript,arrays,Javascript,Arrays,目标:给定一个混合类型数组,确定每个级别的元素数量。如果在同一级别上有两个子数组,则它们的每个元素都将计入该级别上的元素总数 方法: Array.prototype.elementsAtLevels = function( level, levelData ) { if ( level == undefined ) { level = 0; } else { level += 1 } if ( levelData == undefined ) { levelData = {}; }

目标:给定一个混合类型数组,确定每个级别的元素数量。如果在同一级别上有两个子数组,则它们的每个元素都将计入该级别上的元素总数

方法

Array.prototype.elementsAtLevels = function( level, levelData ) {
  if ( level == undefined ) { level = 0;  } else { level += 1 }
  if ( levelData == undefined ) { levelData = {}; }
  if ( levelData[level] == undefined ) { levelData[level] = this.length} else { levelData[level] += this.length }
  this.map(function(e, i) {if (Array.isArray(e)){ e.elementsAtLevels(level, levelData) }})
  return levelData
}
测试用例:

[
  1,      // 0: 1
  1,      // 0: 2
  1,      // 0: 3
  1,      // 0: 4
  [       // 0: 5
    2,    // 1: 1
    2,    // 1: 2
    2     // 1: 3
  ], 
  [       // 0: 6
    [     // 1: 4
      3,  // 2: 1
      3   // 2: 2
    ],   
    [     // 1: 5
      [   // 2: 3
        4 // 3: 1
      ]
    ]
  ]
].elementsAtLevels()

// Object [ 6, 5, 3, 1 ]
问题
有没有更有效的方法来计算这个问题?

这个递归函数应该可以完成这项工作

设arr=[1,1,1,1[2,2,2],[3,3],[4]];
Array.prototype.ElementSatLevel=函数(){
返回此.reduce((acc、el、索引、currentArray)=>{
if(数组isArray(el)){
返回acc.concat(el.elementsAtLevels());
}
返回[currentArray.length];
}, [])
}

console.log(arr.elementsAtLevels())我编写了一些与您所拥有的非常相似的东西,并且在一个非常基本的基准测试中,它只花了不到一半的时间运行

设a=[1,1,1,1,[2,2,2],[3,3],[4]];
Array.prototype.elementsAtLevels2=函数(级别,lData){
如果(!level | |!lData){
级别=0;
lData={};
}
如果(!(以lData表示的级别)){
lData[level]=此长度;
}否则{
lData[level]+=this.length;
}
这个.forEach(函数(v){
if(数组isArray(v))
v、 元素级别2(级别+1,lData);
});
返回lData;
}

log(a.elementsAtLevels2())此功能的性能与您的大致相同,但至少给出了正确的结果:

函数元素SATLEVEL(数组,结果=[],级别=0){
结果[级别]=(结果[级别]| | 0)+array.length
水平仪++
for(阵列常数){
if(数组isArray(el))
元素级别(el、结果、级别)
}
返回结果
}

log(elementsAtLevel([1,1,1,1[2,2,2],[3,3],[4]]])
以下是我对它的看法。它与您的类似,但它不会更改原型,它使用数组而不是对象来返回

函数数组计数器(arr、level、levelData){
如果(级别===无效0){
级别=0;
}
如果(levelData==void 0){
levelData=[];
}
//设置级别的默认值
如果(levelData[level]==void 0){
levelData[level]=0;
}
//计数长度
levelData[级别]+=阵列长度;
//循环浏览列表项
对于(变量i=0;i日志(arrayCounter(数据))不要变异内置代码'prototypes@JoshfromQaribou为什么?输出应该是什么样子?请分享准确的格式。@joshfromqaribu-nope,因为在第一级还有两个其他列表,这些是元素(至少是我所需要的函数)@sumneun您需要一个更有效的解决方案。您认为这种方式有哪些改进?如果您想进行一些常规检查,您可能需要在stackexchange站点上询问。如果我们在同一级别上有多个子数组,则lData[level]将在该级别的最后一个子数组中填充长度。。。剩余子数组长度被覆盖。。。我们是否应该按照问题陈述添加它们?@ShivajiVarma很好的一点,我已改为回答添加所有子数组长度。@Joel是的,我的复制粘贴似乎遗漏了else+=部分:P(现在更正)我认为在复杂性方面你不能做太多,您必须在每个级别上循环每个元素,以检查当前元素是否为数组,然后再递归,但您不需要使用
concat
reduce
重新创建数组。