javascript - 切换索引后数组未更新
问题描述
我正在开发用于排序算法的可视化工具。在我进入选择排序之前,一切都按预期工作。我知道选择排序将通过并搜索 MINIMUM 值,然后交换它在数组中开始的索引。但是,每次通过时,该i
值都不会改变。我通过更改索引在循环中表示的块的颜色来测试它,i
它永远不会改变,所以 MINIMUM 值只是不断切换到原来的i
位置。您可以在 GitHub Pages 上查看我的项目,只需使用左侧导航栏选择选择排序,您就可以看到我遇到的问题。底部片段是我的swap
函数,它没有使用任何其他排序方法执行此操作,只有选择排序。
Github Pages
-- https://kevin6767.github.io/sorting-algorithm-visualization/
选择功能
async function selectionSort() {
let blocks = document.querySelectorAll('.block');
for (let i = 0; i < blocks.length; i++) {
// Assume a minimum value
let min = i;
for (let j = i + 1; j < blocks.length; j++) {
blocks[j].style.backgroundColor = '#FF4949';
blocks[min].style.backgroundColor = '#13CE66';
blocks[i].style.backgroundColor = 'orange';
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, frame_speed)
);
const value1 = Number(blocks[j].childNodes[0].innerHTML);
const value2 = Number(blocks[min].childNodes[0].innerHTML);
if (value1 < value2) {
blocks[min].style.backgroundColor = '#58B7FF';
min = j;
}
blocks[j].style.backgroundColor = '#58B7FF';
}
if (min !== i) {
let tmp = blocks[i];
blocks[i] = blocks[min];
blocks[min] = tmp;
await swap(blocks[i], blocks[min]);
blocks = document.querySelectorAll('.block');
}
// Swap if new minimun value found
blocks[i].style.backgroundColor = '#58B7FF';
}
}
交换功能
function swap(el1, el2) {
return new Promise((resolve) => {
const style1 = window.getComputedStyle(el1);
const style2 = window.getComputedStyle(el2);
const transform1 = style1.getPropertyValue('transform');
const transform2 = style2.getPropertyValue('transform');
el1.style.transform = transform2;
el2.style.transform = transform1;
// Wait for the transition to end!
window.requestAnimationFrame(function () {
setTimeout(() => {
container.insertBefore(el2, el1);
resolve();
}, 300);
});
});
}
解决方案
我最终修复了它。看来我必须从 .querySelectorAll 获取 Nodelist 数组,然后使用 .Arrayfrom() 将其转换为数组,这在谷歌搜索后非常简单。从那时起,我需要弄清楚如何在每次传递时更新数组,这又一次像从另一个索引移动一个索引一样简单。
答案中有趣的部分是我将如何更新 Nodelist 本身,这样我的所有 css 代码仍然可以工作(这是一个排序可视化工具,因此它会显示它所在的元素并用颜色突出显示它)。然而,答案就在我面前。即使我将 Nodelist 数组变成了一个常规数组,我仍然能够对其应用样式。这意味着我根本不必改变 Nodelist 数组,只需在函数中保留一个单独的数组即可使用。
PS。该算法在上面的代码片段中确实有很多问题,因为我在 if 语句中比较了 2 个字符串(value1 和 value2),这是导致很多实际算法错误的原因,只需在周围添加一个 Number() 函数即可解决我的innerhtml代码。
选择
async function selectionSort() {
let blocks = document.querySelectorAll('.block');
let convertedBlocks = Array.from(blocks);
let len = convertedBlocks.length;
for (let i = 0; i < len; i++) {
let min = i;
for (let j = i + 1; j < len; j++) {
convertedBlocks[j].style.backgroundColor = 'red';
convertedBlocks[min].style.backgroundColor = 'green';
convertedBlocks[i].style.backgroundColor = 'orange';
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, frame_speed)
);
if (
Number(convertedBlocks[min].childNodes[0].innerHTML) >
Number(convertedBlocks[j].childNodes[0].innerHTML)
) {
convertedBlocks[min].style.backgroundColor = '#58B7FF';
min = j;
}
convertedBlocks[j].style.backgroundColor = '#58B7FF';
}
if (min !== i) {
let tmp = convertedBlocks[i];
convertedBlocks[i] = convertedBlocks[min];
convertedBlocks[min] = tmp;
await swap(convertedBlocks[i], convertedBlocks[min]);
}
convertedBlocks[min].style.backgroundColor = '#58B7FF';
convertedBlocks[i].style.backgroundColor = '#58B7FF';
}
}
推荐阅读
- c - C风格的宏编译
- powershell - Copy-Item 使用带有通配符的 list.txt 作为参考
- python - 子集化后如何添加列?
- reactjs - 为什么 setState 在值保持不变时重新渲染组件
- c++ - ExternalProject_Add 用于 gflags,但构建多次
- laravel - 在后台执行 Laravel/Symfony/Artisan 命令无法实时运行
- python - 如何在 CSV 文件中选择一列以使用 python 进行标记化?
- c# - mongodb 项目元素到 C# 数组属性
- c# - 如何使用 Azure SDK 在 c# .net core 中创建类型为“Web App bot”的资源
- testng - 从变量设置 invocationCount