[英]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.