javascript - 在 JS 中,anArray = [] 有效,但 abArray.splice(0, anArray.length) 和 anArray.length=0 在以下代码中产生不正确的结果 :

标签 javascript arrays multidimensional-array

我在附加代码中有几个版本的简单嵌套“for 循环”。我想为循环的每次迭代重用相同的数组,而不是每次迭代都创建一个新数组,因为显然这使用了大量内存并为收集创建了多余的垃圾。

此代码的结果应该是一个数组数组,其中包含给定的较大数组数组的子集。相同的简单代码的工作方式不同,具体取决于我用来清除外部循环内的中间一维数组以重用它的方法。具体来说,anArray=[] 用于清除 anArray,但是 anArray.length=0anArray.splice(0, anArray.length)在我的代码中产生不正确的结果。

我知道如何让它工作,我知道如何“更好”地编写代码。这是从复杂代码中的函数中提取出来的,以隔离似乎是错误的东西。我想知道的是,为什么第二个和第三个例子没有按预期工作?

披露:我为 DSP 编写了大量 C 语言和汇编代码,但我没有 JavaScript 经验。请赐教!我缺少哪些知识可以使这些结果易于理解?

如果您复制下面的代码并将其粘贴到某处以运行它,您会非常清楚地看到发生了什么。请单独复制并运行每个示例,否则它们可能会相互作用并使水域更加困惑。

有效的代码是这样的:

var sets = [
  [1, 2, 3, 4, 5, 6],
  [10, 20, 30, 40, 50, 60],
  [100, 200, 300, 400, 500, 600]
] //given array of 3 arrays.
var singleSubset = []; // this simple array will hold a different subset each iteration.
var arrayOfSubsets = []; // this becomes the array of arrays that are subsets of the set arrays. 
var subsetBounds = [1, 5]; // first and last+1 indices of the subsets to be extracted.

for (var i = 0; i < 3; i++) {
  singleSubset = []; // clear this array each outer iteration so we can use .push
  for (var di = subsetBounds[0]; di < subsetBounds[1]; di++) {
    singleSubset.push(sets[i][di])
  };
  arrayOfSubsets.push(singleSubset); // push each subset array on to the output array of arrays.                
}

for (j = 0; j < 3; j++) {
  console.log(arrayOfSubsets[j]);
} // display result:

[2, 3, 4, 5]
[20, 30, 40, 50]
[200, 300, 400, 500]

这是预期的并且是正确的。

这是使用 .length=0 的非常相似的代码,但它不起作用:

var sets = [
  [1, 2, 3, 4, 5, 6],
  [10, 20, 30, 40, 50, 60],
  [100, 200, 300, 400, 500, 600]
] //given array of 3 arrays.
var singleSubset = []; // this simple array will hold a different subset each iteration.
var arrayOfSubsets = []; // this becomes the array of arrays that are subsets of the set arrays. 
var subsetBounds = [1, 5]; // first and last+1 indices of the subsets to be extracted.

for (var i = 0; i < 3; i++) {
  singleSubset.length = 0; // clear this array each outer iteration so we can use .push
  for (var di = subsetBounds[0]; di < subsetBounds[1]; di++) {
    singleSubset.push(sets[i][di])
  };
  arrayOfSubsets.push(singleSubset); // push each subset array on to the output array of arrays.                
}

for (j = 0; j < 3; j++) {
  console.log(arrayOfSubsets[j]);
} // display result:

[200, 300, 400, 500]
[200, 300, 400, 500]
[200, 300, 400, 500]

这显然不是预期的,也不正确。

这是一个避免使用 .push 的版本,因此不需要在迭代之间清除中间数组。尽管如此,=[] 方法仍然有效,而且实际上仍然是必需的,否则它无法正常工作。通过根据需要取消注释,将此代码与各种清除方法中的每一种一起尝试:

var sets = [
  [1, 2, 3, 4, 5, 6],
  [10, 20, 30, 40, 50, 60],
  [100, 200, 300, 400, 500, 600]
] //given array of 3 arrays.
var singleSubset = []; // this simple array will hold a different subset each iteration.
var arrayOfSubsets = []; // this becomes the array of arrays that are subsets of the set arrays. 
var subsetBounds = [1, 5]; // first and last+1 indices of the subsets to be extracted.

for (var i = 0; i < 3; i++) {
  singleSubset = []; // works and is required or it doesn't work.  But comment it out and try:
  // singleSubset.length = 0;  // or try:
  // singleSubset.splice(0, singleSubset.length);  // or for extra madness try:
  // singleSubset.length = 0; singleSubset = []; // as placing .length=0 ahead of =[] produces bad output too! 
  for (var di = subsetBounds[0]; di < subsetBounds[1]; di++) {
    singleSubset[di - subsetBounds[0]] = sets[i][di];
  }
  arrayOfSubsets[i] = singleSubset;
}

for (j = 0; j < 3; j++) {
  console.log(arrayOfSubsets[j]);
} // display result:

[200, 300, 400, 500]
[200, 300, 400, 500]
[200, 300, 400, 500]

这显然不是预期的,也不正确。

=[] 选项之前的 .length=0 产生这个:

[]
[]
[200, 300, 400, 500]

这对任何人都有意义吗? 我很想知道多维数组是如何用 C 语言表达的。直观起来要容易得多! 当然,如果可以使用更好的 JS 在一条语句中将二维数组的子集提取为较小的二维数组,我也会为此感谢你。

最佳答案

如果您不在每次循环中都创建一个新数组,arrayOfSubsets 的所有元素都将是对同一个数组的引用。当您改变它的长度、拼接它或将新元素推到它上面时,它们都会发生这些变化。

因此,您要么每次循环都需要创建一个新数组(这是正常方式),要么在将其推送到包含数组时制作一个副本:

arrayOfSubset.push(singleSubset.slice());

关于javascript - 在 JS 中,anArray = [] 有效,但 abArray.splice(0, anArray.length) 和 anArray.length=0 在以下代码中产生不正确的结果 :,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58569401/

相关文章:

C++ 复制多维 vector

c++ - 多维锯齿状图

Javascript - moment.js 日期对象到 unix 字符串

JavaScript - 对从 Container 中移除元素非常困惑

javascript - 在 javascript 方法中定义的数组的生命周期

javascript - 向数组添加通用对象和格式

javascript - 如何将多维 JSON 对象转换为 javascript 数组

javascript - keyup函数的Javascript问题-尝试多次使用页面上的同一表单域,但只有第一个表单域有效

javascript - Sails.js:从 Controller 调用YouTube服务

java - 如何按顺序打印两个相邻的增强型 for 循环