Learn Basic Algorithmic Thinking by Building a Number Sorter - Step 40

Tell us what’s happening:

So I know what I need to do to complete this step, I just don’t understand how this loop works. Why are we doing j-- instead of j ++?

Your code so far

<!-- file: index.html -->

/* file: styles.css */

/* file: script.js */
// User Editable Region

const insertionSort = (array) => {
  for (let i = 1; i < array.length; i++) {
    const currValue = array[i];
    let j = i - 1;

    while (j >= 0 && array[j] > currValue) {
      array[j + 1] = array[j];
      j--;
    }
    array[j + 1] = currValue;
  }

}

// User Editable Region

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3 Safari/605.1.15

Challenge Information:

Learn Basic Algorithmic Thinking by Building a Number Sorter - Step 40

For loops are a simple process but kind of hard to understand they add on until a condition is meant.

type i++ increment the variable i by 1. It is the equivalent to i = i + 1. i– decrements (decreases) the variable i by 1. It is the equivalent to i = i - 1.

In fact a while loop is just a for loop in a way, also there is another way to write a for loop in which it breaks it down into separate expressions. I hope this helps.

Short answer: It’s j-- and not j++ because, for each iteration of the outer loop, the inner loop needs to iterate backwards over all of the values preceding array[i] and see if they are greater than the value at array[i]. If they are, it will push them one index to the right. When this process is repeated over the entire array, the array will come out sorted.


Long answer: This is because of the way that the insertion sort algorithm works. Insertion sort works by iterating over each of the numbers in the array, and for each number, iterating over all the numbers preceding it, pushing them to the right if they are higher than it, therefore “inserting” it in its sorted position. This goes on until the entire array is sorted.

In each iteration of the outer loop, you select a position in the list (i) and then iterate over all of the positions preceding it in the list using the inner loop (j).

You start with i = 1. The element at index 1 is the second element, since arrays (and most things in programming) are zero-indexed, meaning the first number is zero. At index 1, the number is 2, so currValue is set to 2. Since j = i - 1, then j = 0. The number at index 0 is 8. Since array[j] > currValue is true because 8 > 2, and j >= 0 is true since 0 >= 0, the while loop runs, copying the value of array[j], which is 8, to array[j+1]. j-- decreases j by 1, making it -1. -1 is not >= 0, so the loop stops.

The value that used to be in array[j+1], which is 2, is stored in currValue. Since j is now -1, array[j+1] now refers to array[0]. array[0] takes the value from currValue, so the order is now [2, 8, 4, 1, 3] instead of [8, 2, 4, 1, 3].

When i=2, the same thing will happen: the loop will iterate over all the indices less than 2, which are array[0] and array[1], and check which of them are greater than the value of array[2]. It will find that 8 > 4, and copy 8 to the right one index. It will then find that !(2 > 8) (the exclamation mark means “is not”), so it will stop the inner loop there, and put the value stored in currValue (which is 4) at array[1]. The order will now be [2, 4, 8, 1, 3].

This will continue until the entire array is sorted, and the order will be [1, 2, 3, 4, 8]


Let me know if that answers your question. I’d be glad to clarify if it’s still unclear.

Edit: It might help to look at a visual demonstration of InsertionSort. Here’s a good visualization: https://www.youtube.com/watch?v=nKzEJWbkPbQ

Thank you! That does make sense.

1 Like

I was also wondering if you could help me understand this code, although this is probably a dumb question, I want to make sure I understand every part of it:

const updateUI = (array = ) => {
array.forEach((num, i) => {
const outputValueNode = document.getElementById(output-value-${i});
outputValueNode.innerText = num;
})
}
I don’t understand where the “num” and “I” parts are coming from.

1 Like

Hi @victoriat420

The .forEach() method accepts three arguments, in the following order:

  1. is the value of the element
  2. is the index of the element
  3. is the array

Happy coding

It’s not a dumb question at all! We’re all here to learn, so never hesitate to ask if you don’t understand something.

Short answer: The .forEach() function iterates over an array and calls a callback function once for each element of the array. As Teller mentioned, that function takes up to three parameters: the first is the element’s value, the second is its index, and the third, if included, is the array itself. The names num and i are arbitrary (although you should give your variables logical names, so num and i are good choices). The computer knows which is which by the order, not the name.


Detailed answer: As Teller said, the .forEach() function accepts a maximum of three parameters. More precisely though, it accepts a callback function which itself accepts up to three parameters. As the name forEach imples, the callback function is called once for each element of the array on which the forEach element is called (here simply called array). The parameters the callback accepts are, in order: the value of the element (here named num), the index of that element in the array (here named i), and the array the element is in (here not included since it wasn’t needed by the callback function).

Note that the names num and i are decided by the programmer. Which variable refers to what is determined by the order, in this case (the first is the element value, the second is the index, the third, if included, is the array). You could’ve named them anything you like, but it’s important to give variables logical names that are easy for you and anyone else reading your code to understand and remember, and it’s programming tradition to use i for the index number.

If we take a look at the code again:

const updateUI = (array = []) => {
  array.forEach((num, i) => {
    const outputValueNode = document.getElementById(output-value-${i});
    outputValueNode.innerText = num;
  })
}

The function .forEach() is being called on the array named array, and it’s being passed an unnamed arrow function as a callback. It will run this callback once for each element of the array. This function takes two parameters: num, which is the value of the element, and i, which is the index of that element in the array. The body of the function does the following.

This line

const outputValueNode = document.getElementById(output-value-${i});

creates a constant JavaScript variable that references the HTML object with the ID #output-value-i, where you replace “i” with the value of the parameter i. #output-value-0 for i=0, #output-value-1 for i=1, and so on.

This line

outputValueNode.innerText = num;

then changes the innerText of that HTML object to the value num.

Therefore, when the .forEach() function is done running, each one of the array.length number of will have a value based on the value of the element at the corresponding index in the array. #output-value-0 will have an innerText equal to the value at array[0], #output-value-1 will have an innerText equal to array[1], and so on.

I hope that helps clear things up. If any further explanation is needed, please let me know.

P.S. The reason we can use the same variable name even though variables declared with const are supposed to constant and un-editable is because the variable outputValueNode is being declared in a for loop. If I understand correctly, the scope of the variable is therefore just that iteration of the loop, and the variable doesn’t exist outside that context, allowing the name to be used again in the next iteration.


Btw, the [] in your code is rendering as a checkbox on the forum, like this: array = . When posting a block of code to the forum, make sure to include a line of three backticks (```) before and after it to ensure it is formatted and rendered properly as code.

For example, if I put this in the editor:

It will render like this to the reader:

const exampleVariable = "example of code block";
console.log(exampleVariable);

If it’s a single line of code or a few words, use a single backtick on each side instead. It will render like this.

This will help make your code clear to others and make it easier for them to help you. Cheers!

1 Like