繁体   English   中英

JavaScript 中的奇怪数组行为

[英]Weird array behavior in JavaScript

我正在尝试编写一个可视化冒泡排序算法的工具。

包含所有要排序的值的数组arr是一个全局变量。 用户单击“填充”按钮btnFill以使用fillArray function 用未排序的随机数填充数组。function 返回一个对象数组: {val: x, col: "y"}其中 x 是值,col 是颜色 class 用于 CSS。

填充数组后,如果用户单击“排序”按钮btnSort ,将调用bubbleSort function 我猜我的问题是:

这个 function 在内循环的每次迭代中保存数组arr的副本。 这是我的一个想法,因为我在使用 setInterval 设置动画时遇到了很多问题 - 我可以在排序的每个阶段保存数组的快照,然后将它传递给 draw function 这样就不会任何 JavaScript 怪异组合循环和间隔。

function 完成运行并期望(至少对我而言)返回一个数组,其中填充了每个循环迭代中的arr数组的副本。

几个小时以来我一直试图理解的实际行为是snapShot数组充满了排序后的arr的 arrays。 所有元素都相同 - 排序为 arrays。这对我来说没有意义,因为在调试时它第一次进入排序循环时在 console.log 中显示为已排序。

我非常感谢任何帮助,谢谢!

--EDIT-- 我知道 snapShot 数组作为 arrays 的数组发送,不会被绘制到屏幕上,但问题出在这之前的某个地方。 由于调试原因更改了该部分

const btnFill = document.querySelector("#btnFill");
const btnSort = document.querySelector("#btnSort");
const container = document.querySelector(".container");

let arr = [];

btnFill.addEventListener("click", function () {
  arr = fillArray();
  draw(arr);
});

btnSort.addEventListener("click", function () {
  let sorted = bubbleSort();
  draw(sorted);
});

function bubbleSort() {
  let snapShots = [];
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = 0; j < arr.length - 1 - i; j++) {
      if (arr[j].val > arr[j + 1].val) {
        let tmp = arr[j].val;
        arr[j].val = arr[j + 1].val;
        arr[j + 1].val = tmp;
        snapShots.push([...arr]);
      }
    }
  }
  return snapShots;
}

function fillArray() {
  const tmp = [];
  const len = 50;
  for (let i = 0; i < len; i++) {
    tmp[i] = { val: Math.floor(Math.random() * 100 + 1), col: "red" };
  }
  return tmp;
}

function draw(array) {
  container.innerHTML = "";
  for (let i = 0; i < array.length; i++) {
    const tmp = document.createElement("div");
    tmp.style.height = array[i].val + "%";
    tmp.classList.add("bar", array[i].col);
    container.appendChild(tmp);
  }
}

它不能像您希望的那样工作的原因是因为您正在对数组进行浅表复制,但是每个 position 中的对象都是相同的引用。

这意味着这部分代码:

    let tmp = arr[j].val;
    arr[j].val = arr[j + 1].val;
    arr[j + 1].val = tmp;

正在更改 object,每个快照元素都指向相同的 position。这就是为什么要对每个数组进行排序的原因,因为您正在创建新的 arrays,并使用相同的对象引用。

为了得到你想要的,你可以做一个deep copy ,这也会创建嵌套值的新引用。

function bubbleSort() {
  let snapShots = [];
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = 0; j < arr.length - 1 - i; j++) {
      if (arr[j].val > arr[j + 1].val) {
        let tmp = arr[j].val;
        arr[j].val = arr[j + 1].val;
        arr[j + 1].val = tmp;
        snapShots.push(JSON.parse(JSON.stringify(arr)));
      }
    }
  }
  return snapShots;
}

其他解决方案(更简单)是更改数组中 object 的 position,而不是更改 object 的属性val

function bubbleSort() {
  let snapShots = [];
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = 0; j < arr.length - 1 - i; j++) {
      if (arr[j].val > arr[j + 1].val) {
        let tmp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = tmp;
        snapShots.push([...arr]);
      }
    }
  }
  return snapShots;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM