'Selection sort animation isn't iterating through the steps of sorting like I intended
Below, I've included the two functions which most likely contain error. The function iterate should pause the program for one second, clear the body of the page, then, for every index in the list colors, create a div with a unique color and height based on a list order. The function selectionSort is a common selection-sort function which, after one iteration of sorting the list order, should execute the function iterate. For some reason, this code produces the final sorted result after one second instead of pausing through every iteration of sorting to display a partially sorted line of divs. Does anyone see any glaring issues with this code? I'll also add that the sleep function itself works properly.
function selectionSort() {
for (i=0; i<order.length-1; i++) {
let minIndex = i;
for (j=i+1; j<order.length; j++) {
if (order[j] < order[minIndex]) {
minIndex = j;
}
}
[order[i], order[minIndex]] = [order[minIndex], order[i]];
iterate();
}
}
async function iterate() {
await sleep(1000);
document.body.innerHTML = "";
for (i=0; i<colors.length; i++) {
let newDiv = document.body.appendChild(document.createElement("div"));
newDiv.style.backgroundColor = colors[order[i]];
newDiv.style.height = ((order[i] * 2.4) + 36).toString() + "px";
}
}
If it helps, this is the full html:
<!DOCTYPE html>
<html>
<title>Sorting Algorythm</title>
<head>
<style>
body {background: black;}
div {margin-left: 0; margin-right: 0; display: inline-block; width: 5.5px;}
</style>
</head>
<body></body>
<script>
var colors = [];
let order = [];
setup();
iterate();
selectionSort();
function setup() {
for (i=16; i<256; i++) {
colors.push("#BB" + i.toString(16) + i.toString(16));
}
for (i=0; i<colors.length; i++) {
order.push(i);
}
shuffle(order);
}
function selectionSort() {
for (i=0; i<order.length-1; i++) {
let minIndex = i;
for (j=i+1; j<order.length; j++) {
if (order[j] < order[minIndex]) {
minIndex = j;
}
}
[order[i], order[minIndex]] = [order[minIndex], order[i]];
iterate();
}
}
async function iterate() {
await sleep(1000);
document.body.innerHTML = "";
for (i=0; i<colors.length; i++) {
let newDiv = document.body.appendChild(document.createElement("div"));
newDiv.style.backgroundColor = colors[order[i]];
newDiv.style.height = ((order[i] * 2.4) + 36).toString() + "px";
}
}
function shuffle(array) {
for (i=array.length-1; i>0; i--) {
let j = Math.floor(Math.random()*(i+1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
</script>
</html>
Solution 1:[1]
You have two main problems:
Every time you have
for (i = 0…, you should be declaringias a variable for that loop instead, likefor (let i = 0….By doing
i = 0instead oflet i = 0(orvar i = 0), you are implicitly creating a global variablei, which means all the loops are accessing and updating the sameiat the same time and screwing everything up. You want a separateifor each loop. This also goes for thejinside the nested loop inselectionSort.Since you are calling
iterate()inside a loop in yourselectionSortfunction, anditerateis async, you have toawait iterate()if you want a pause between each loop inselectionSort. That also meansselectionSortneeds to be async as well.
Making those two changes we get this (check your console):
var colors = [];
let order = [];
setup();
iterate();
selectionSort();
function setup() {
for (let i = 16; i < 256; i++) {
colors.push("#BB" + i.toString(16) + i.toString(16));
}
for (let i = 0; i < colors.length; i++) {
order.push(i);
}
shuffle(order);
}
async function selectionSort() {
for (let i = 0; i < order.length - 1; i++) {
let minIndex = i;
for (let j = i + 1; j < order.length; j++) {
if (order[j] < order[minIndex]) {
minIndex = j;
}
}
[order[i], order[minIndex]] = [order[minIndex], order[i]];
console.log('calling iterate', i);
await iterate();
}
}
async function iterate() {
await sleep(1000);
document.body.innerHTML = "";
for (let i = 0; i < colors.length; i++) {
let newDiv = document.body.appendChild(document.createElement("div"));
newDiv.style.backgroundColor = colors[order[i]];
newDiv.style.height = ((order[i] * 2.4) + 36).toString() + "px";
}
}
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
body {
background: black;
}
div {
margin-left: 0;
margin-right: 0;
display: inline-block;
width: 5.5px;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | cjl750 |
