DEV Community

Cover image for A Look into Processing MultiDimensional Arrays Using Javascript
Maria del Carmen Santiago
Maria del Carmen Santiago

Posted on

A Look into Processing MultiDimensional Arrays Using Javascript

Understanding multidimensional arrays by solving a simple two-dimensional Harry Potter Challenge using Vanilla Javascript.

The Challenge

The Hogwarts Express has added several new stops on its journey from Platform 9 ¾ in London’s King’s Cross Station to Hogsmeade Station in Hogwarts School of Witchcraft and Wizardry. Dumbledore needs a management tool with which a crew member can input the numbers of passengers boarding and disembarking at each station. With these numbers, this tool will automatically calculate the number of passengers on board the train.

Arrays

According to MDN web docs, arrays are “list-like objects whose prototype has methods to perform traversal and mutation operations”.

There is more than one way to create an array. You can use the array constructor const array1 = new Array(“item1”, “item2”), but it is recommended for both readability and speed to use the array literal method. Below we will use the literal method to create a one-dimension array with the names of the train stations from London to Hogwarts.

const stations = [
   "King's Cross",
   'Waverly',
   'Weasley',
   'Cardiff Central',
   'Hogsmeade',
];
Enter fullscreen mode Exit fullscreen mode

A two-dimensional array is just a one-dimensional array inside another array. For each station, a pair of elements will be added in a [ [b1, d1], [b2, d2] … ] fashion, where b represents the number of passengers that have boarded the train and d represents the number of passengers that have disembarked the train. For now, we will just create an empty array that will be populated with new information submitted by the crew member in charge of the train’s passenger capacity.

const passengerLog = [ ];
Enter fullscreen mode Exit fullscreen mode

Accessing HTML Elements

What is important for us to know about the HTML are the class names of the elements inside the form.

Note: There are different ways to name your classes. In this project, I used the BEM naming convention. For more on this, you can do some research on naming conventions here.

  • Station name’s display area: .station__name
  • Passengers boarding input box: .passengers__in
  • Passengers disembarking input box: .passengers__out
  • Submit button: .button__add-passengers
  • Passengers onboard display area: .passengers__total

HTML:

<form>
      <table>
        <tr>
          <th colspan="2">STATION</th>
        </tr>
        <tr>
          <td colspan="2" class="station__name"></td>
        </tr>
        <tr>
          <th>IN</th>
          <th>OUT</th>
        </tr>
        <tr>
          <td class="input__in-out">
            <input
                   class="passengers__in"
                   type="number"
                   min="0"
                   />
          </td>
          <td class="input__in-out">
            <input
                   class="passengers__out"
                   type="number"
                   min="0"
                   value="0"
                   />
          </td>
        </tr>
        <tr>
          <td colspan="2">
            <button type="submit" class="button__add-passengers">
              Submit
            </button>
          </td>
        </tr>
      </table>
      <br />
      <p class="passengers__total"></p>
    </form>
Enter fullscreen mode Exit fullscreen mode

Next, we will be using the querySelector method and using the class selectors mentioned before in order to return the elements we need. The form itself has no class name so you can use the same method, but omitting the . at the beginning of the selector name.

JavaScript:

const stationName = document.querySelector('.station__name');
const passengersIn = document.querySelector('.passengers__in');
const passengersOut = document.querySelector('.passengers__out');
const buttonAddPassengers = document.querySelector('.button__add-passengers');
const passengersTotal = document.querySelector('.passengers__total');
const form = document.querySelector('form');
Enter fullscreen mode Exit fullscreen mode

Adding Elements to Multidimensional Arrays

The push method will add elements to the end of an array. If we have an array const letters = [‘b’, ‘c’, ‘d’] and want to add a fourth letter we just need to use the array.push(‘e’) method to add that letter. This means the output for console.log(letters) will go from [‘b’, ‘c’, ‘d’] to [‘b’, ‘c’, ‘d’, ‘e’].

As mentioned before, multidimensional arrays are just one-dimensional arrays inside other one-dimensional arrays so the same method can be used to add an array into an array. We already created an array called passengerLog. Before leaving each station, the crew member in charge will use the form in order to submit two numbers. The number of passengers that boarded the train and the number that disembarked at said station.

These two numbers will need to be added to the passengerLog array using the push method passengerLog.push([passengersInValue, passengersOutValue]);. When adding an element in the form of an array you will be creating a two-dimensional array that will be constructed as follows: [ [passengersInStationOne, passengersOutStationOne], [passengersInStationTwo, passengersOutStationTwo] ... ].

const passengersIn = document.querySelector('.passengers__in');  // already established 
const passengersOut = document.querySelector('.passengers__out');  // already established 

const passengerLog = []; // already established 

function addToPassengerLog() {
   let passengersInValue = passengersIn.value;
   let passengersOutValue = passengersOut.value;

  // Replace empty input boxes with 0 before adding to log
  // Add last entry to the passenger log
   if (passengersInValue && passengersOutValue) {
      return passengerLog.push([passengersInValue, passengersOutValue]);
   } else if (passengersInValue && !passengersOutValue) {
      return passengerLog.push([passengersInValue, 0]);
   } else if (!passengersInValue && passengersOutValue) {
      return passengerLog.push([0, passengersOutValue]);
   } else {
      return passengerLog.push([0, 0]);
   }
}
Enter fullscreen mode Exit fullscreen mode

I’ve gone a step further for this project and added an if...else statement to check for empty input logs and change them to zero before adding the input values into the main array. The if...else statements all have a logical && operator which will return true if both statements on either side of the && operator are true.

If (passengersInValue && passengersOutValue), means that passengersInValue and passengersOutValue exist. So, as we state below it, both values will be added to the passengerLog array. However, if (passengersInValue && !passengersOutValue) this means that the passengersInValue exists, but the passengersOutValue does not (that is what the ! not operator is for). That input box has been left empty on the form. Hence, we add the passengersInValue value and a zero, as stated below that else if statement.

Extra: If we wished to add an element (or elements) to the beginning of an array, we could use the unshift method. We can take that const letters = [‘b’, ‘c’, ‘d’, ‘e’] array I used as an example before and add an a at the beginning as follows: array.unshift(‘a’). Now the output for console.log(letters) will go from [‘b’, ‘c’, ‘d’, ‘e’] to [‘a’, ‘b’, ‘c’, ‘d’, ‘e’].

Removing Elements from Multidimensional Arrays

The method used to remove the last element from an array is called pop. This will be an easy one. As we push elements into the array we get a two-dimensional array that looks like this: [ [passengersInStationOne, passengersOutStationOne], [passengersInStationTwo, passengersOutStationTwo] ]. When we use the pop method, it will remove not just passengersOutStationTwo, but the whole [passengersInStationTwo, passengersOutStationTwo] array as this whole array is considered an element of the passengerLog array.

const passengerLog = []; // already established 

function removeFromPassengerLog() {
  // Remove last entry from passenger log
  return passengerLog.pop();
}
Enter fullscreen mode Exit fullscreen mode

Extra: If we wished to remove an element from the beginning of an array, we could use the shift method. We can take that const letters = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’] array and remove the a at the beginning as follows: array.shift(). Now the output for console.log(letters) will go from [‘a’, ‘b’, ‘c’, ‘d’, ‘e’] to [‘b’, ‘c’, ‘d’, ‘e’].

Reduce Multidimensional Arrays

The reduce method will execute a function determined by you on each element. After it is done it will return a single output value.

Reduce can take in four arguments. An accumulator(acc), current value (cur), current index (idx), and source array (src) with a syntax array.reduce(function(acc, cur, idx, src), initialValue).

For this example, we will only use the first two arguments (which are the only two that are required). Applying reduce to the passengerLog array means that for each [passengersInStationX, passengersOutStationX] entry we will execute the function provided. The results will be stored inside the accumulator (acc) before going to the next entry, executing the function on that next set of values, and adding the result to the accumulator.

Side Note: Arrays are zero-based. To access an item in an array you can use the index position as follows: const letters = [‘b’, ‘c’, ‘d’, ‘e’] console.log(letters[0]) //output: ‘b’ console.log(letters[1]) //output: ‘c’. As for multidimensional arrays, if we have const letters2 = [ [‘b’, ‘c’], [‘d’, ‘e’] ] and we want to access the letter ‘c’ we would need to use the index of the first element [‘b’, ‘c’] and then the index of the letter ‘c’ inside that array. That means console.log(letters2[0]) //output: [‘b’, ‘c’], whereas console.log(letters2[0][1]) //output: ‘c’.

function calculatePassengersTotal() {
  // Calculate number of passengers onboard.
   return passengerLog.reduce((acc, cur) => {
      return (acc += cur[0] - cur[1]);
   }, 0);
}
Enter fullscreen mode Exit fullscreen mode

Another way of doing the same thing would be as follows:

function calculatePassengersTotal() {
  // Calculate number of passengers onboard.
  return passengerLog.reduce((onboard, [boarding, disembarking]) => {
      return (onboard += boarding - disembarking);
   }, 0);
}
Enter fullscreen mode Exit fullscreen mode

Next Station!

The names of the stations are given to us so the management tool will automatically let the crew member in charge know which station they are at.

We will declare a couple of variables first. One for the index of the station, and since arrays are zero-based we will assign the number zero to it. The second variable will store the length of the array containing the names of the stations.

Side Note: The length property returns the number of elements in an array. Arrays may be zero-based, but for this property we start counting from one. For a multidimensional array like const letters2 = [['b', 'c'], ['d', 'e']]; we would get an output of 2 from console.log(letters.length) and not 1 (as if we started counting from zero) nor 4 (as if we were counting each letter as a separate element of the letters2 array).

The basic form of this nextStation function is stationName.innerHTML = stations[stationIndex] so as to change the HTML content of the stationName element to the station on the index stationIndex. Since we assigned that to zero the first station will be King's Cross.

const stations = [     // already established 
   "King's Cross",
   'Waverly',
   'Weasley',
   'Cardiff Central',
   'Hogsmeade',
];   

let stationIndex = 0;
let stationLength = stations.length;   // output: 5

function nextStation(stationIndex) {
  // Display name of station. 
  // For the last two stations the text on the button will change.
  // On the last station the button will be disabled.
   if (stationIndex == stationLength - 2) {
      buttonAddPassengers.textContent = 'Last Station Coming Up';
   } else if (stationIndex == stationLength - 1) {
      buttonAddPassengers.textContent = 'End of Journey';
      buttonAddPassengers.disabled = true;
   } 
   return (stationName.innerHTML = stations[stationIndex]);
}

nextStation(stationIndex);
Enter fullscreen mode Exit fullscreen mode

I have added an if...else statement to change the text content of the submit button for when the train is approaching the destination and to change it again when the journey has ended (disabling the button at the same time).

Submit Passenger Log

The main function that will be executed when we hit that submit button on the form is the one below. On it we will first call the addToPassengerLog() function to add (or push) the inputs logged by the crew member. Then we declare a variable and assign the results from the calculatePassengersTotal() function, which will give us the number of passengers on board.

If the total number of passengers is zero or more then we display the number in the assigned space provided using innerHTML on that element. Next, we clear the input boxes using form.reset();. Finally, we increase the stationIndex by one and, with that, display the next station using the nextStation(stationIndex) function.

If the total number of passengers is less than zero, then that means there was a mistake since we can’t have a negative number of passengers on board. To give the crew member a chance to correct that mistake we will remove that last entry from the log using the removeFromPassengerLog() function, clear the input boxes and send a message about the mistake for which the crew member will have to confirm they have read using window.confirm( ).

const stationName = document.querySelector('.station__name');  // already established 
const passengersIn = document.querySelector('.passengers__in');  // already established 
const passengersOut = document.querySelector('.passengers__out');  // already established 
const passengersTotal = document.querySelector('.passengers__total');  // already established 
const form = document.querySelector('form');  // already established 

function submitPassengerLog(e) {
   e.preventDefault();
   addToPassengerLog();
   let totalPassengers = calculatePassengersTotal();

  if ( totalPassengers >= 0 ) {
    // Display the total number of passengers on board.
    passengersTotal.innerHTML = `Passengers onboard: ${totalPassengers}`
   }
   // Clear input boxes.
   form.reset();
   // Display next station
   stationIndex++;
   nextStation(stationIndex);

  } else {

    removeFromPassengerLog();
    form.reset();
    window.confirm("Check how many witches and wizards are on the train./nYou can't have more of them leaving the train than are onboard.");
  }

}

form.addEventListener('submit', submitPassengerLog);
Enter fullscreen mode Exit fullscreen mode

Demo

For more on arrays, take a look at MDN web docs in arrays. I hope that with what we have seen here together you now have a better understanding of multidimensional arrays and how to work with them on more complicated projects.

If you liked what you read hit that ❤️ on the left or wherever it is. If you really liked it don’t forget to share it with the community by hitting that dot-dot-dot icon near the heart.

💻 article.close()

Resources

Top comments (0)