Lekazard
Lekazard

Reputation: 13

How to compare multidimensional nested arrays in javascript?

So far I have managed to make simple code, where out of an array of numbers I'm able to get the largest and smallest value by comparison and print out the results in an html-paragraph. But here's where things go beyond my limited comprehension:

a) how the functions need to be changed, if I want to make it more complex by changing the array ([1,2,3] into a multidimensional array containing not one but two values [[a,1],[b,2],[c,3]? The comparison would be between the latter numeral value.

b) how do the document.write need to be modified so it shows both values, [a,1] instead of just [1]

c) if I delete the first line with id="display-array" the document.write doesn't work anymore. why?

I just started out with javascript only a couple of weeks ago so every help and simple answers are highly appreciated. Thanks.

        <p id="display-array"></p>
<script>
    var array = [10,2,30,4]
    //var array = [[a,10],[b,2],[c,30],[d,4]]
    for (var i = 0; i < array.length; i++)
    document.getElementById("display-array").textContent = array.join(", ")

    function mostExpensive(array){
        let j;
        let max = array[0]
        for (j = 1; j < array.length; j++){
            if (array[j] > max) max = array[j];
        }
        return max
    }
    document.write("Most expensive price: " + mostExpensive(array));
    </script><br>
    <script>
    function mostCheap(array){
        let jj;
        let min = array[0]
        for (jj = 0; jj < array.length; jj++){
            if (array[jj] < min) min = array[jj];
        }
        return min
    }
    document.write("Cheapest price: " + mostCheap(array));
    </script>

Upvotes: 1

Views: 103

Answers (2)

Brother58697
Brother58697

Reputation: 3178

You can use Array.prototype.sort (1) to sort the array based on the second value in inner arrays.

You don't need to edit the document.write functions if you don't want to. It'll just convert the array to a string using the default toString method (2).

You can also join it with : if you want which is what I did in the 'most cheap' below to show the output, and if you want more control, save it to a variable and use the specific array indices to make a string. Assuming we saved most expensive to max, then something like:

document.write('Most expensive item is' + max[0] + ' at a price of ' + max[1])

or you can use template literals with backticks (`) (3) like this:

document.write(`Most expensive item is ${max[0]} at a price of ${max[1]}`)

I used template literals in an extra example below.

<p id="display-array"></p>
<script>
    var array = [['a',10],['b',2],['c',30],['d',4]]
    for (var i = 0; i < array.length; i++)
    document.getElementById("display-array").textContent = array.join(", ")

    function mostExpensive(array){
       let sorted = array.sort((a, b) => b[1] - a[1]);
       return sorted[0]
    }
    
    document.write("Most expensive price: " + mostExpensive(array));
</script><br>
<script>
     function mostCheap(array){
       let sorted = array.sort((a, b) => a[1] - b[1]);
       return sorted[0]
    }
    document.write("Cheapest price: " + mostCheap(array).join(':'));
</script><br>
    
 <script>
    const cheapest = mostCheap(array);
    document.write(`Using template literals, the cheapest is ${cheapest[0]} and it costs ${cheapest[1]}`)
</script>

Edit: I also want to add that if you have control over how the array is generated, you're better off using an array of objects instead of an array of arrays since we can differentiate what the first element and the second element represent:

<p id="display-array"></p>
<script>
    var array = [
      {name: 'a', price: 10},
      {name: 'b', price: 20},
      {name: 'c', price: 30},
      {name: 'd', price: 40}
    ]
    
    // Remove the loop
    // Use array.prototype.map() to map objects to strings 
    document.getElementById("display-array").textContent = array
      .map(item => `${item.name} ${item.price}`)
      .join(", ")
    
    
    function mostExpensive(array){
       let sorted = array.sort((a, b) => b.price - a.price);
       return sorted[0]
    }
    
    const highest = mostExpensive(array)
    document.write(`Most expensive item is ${highest.name} which costs ${highest.price}`);
</script> <br>
    
<script>
     function mostCheap(array){
       let sorted = array.sort((a, b) => a.price - b.price);
       return sorted[0]
     }
    
    const cheapest = mostCheap(array);
    document.write(`Cheapest item is ${cheapest.name} which costs ${cheapest.price}`)
</script><br>

Upvotes: 1

Ma3x
Ma3x

Reputation: 6549

You should probably use built-in functions to search for max (and min) values inside arrays, but if you want to learn how to access multi-dimensional arrays then continue reading.

a) how the functions need to be changed, if I want to make it more complex by changing the array ([1,2,3] into a multidimensional array containing not one but two values [[a,1],[b,2],[c,3]? The comparison would be between the latter numeral value.

b) how do the document.write need to be modified so it shows both values, [a,1] instead of just [1]

Since due to b) you want to return the "whole item" from the top-level array, you have two options:

  1. you can track whole items in max (or min) variables inside your functions
  2. or, you can track the index of the max (or min) item in those variables

I will show you the approach for 1.

Due to a) and b) you want to store the whole item when assigning to min and max variables. But this will be already the case automatically when you change the array from a one-dimentional array to a two-dimensional array.

First you change the array to const array = [["a",10],["b",2],["c",30],["d",4]].

Instead of var use let for variables and const for immutable values, unless you need the hoisting behavior that var provides.

All assignments to max remain unchanged let max = array[0] and max = array[j]; and thus also the return statement remains unchanged return max. Same goes for min.

What you do need to change, however, is the part of code where you compare array item values (the inner price value) to the current max (or min) item values (to its inner price value).

This code

if (array[j] > max)

changes to

// work with the value at index [j] in the first dimension and
// at index [1] in the second dimension, and also compare with max[1]
if (array[j][1] > max[1])

The write statements don't really need to change unless you would want to format the output differently than c,30 for example.

In that case you can just format the string in the way you would want it to display.

Example:

const expensive = mostExpensive(array)
document.write(`Most expensive price is ${expensive[1]} USD for ${expensive[0]}`);

c) if I delete the first line with id="display-array" the document.write doesn't work anymore. why?

Due to the line that is accessing the element with id display-array

document.getElementById("display-array").textContent = // ...

If you remove the element with id="display-array" then the line above throws an error and JS stops executing that script tag.

And here it everything above in a working example

<p id="display-array"></p>
<script>
    //const array = [10,2,30,4]
    const array = [["a",10],["b",2],["c",30],["d",4]]
    for (let i = 0; i < array.length; i++)
    document.getElementById("display-array").textContent =
        array
            .map(item => {
                // map the items (to string) however you want them to display
                return `${item[0]} is ${item[1]} USD`
            })
            .join(", ")

    function mostExpensive(array){
        let max = array[0]
        for (let j = 1; j < array.length; j++){
            // work with the value at index [j] in the first dimension and at index [1] in the second dimension, and also compare with max[1]
            if (array[j][1] > max[1]) max = array[j];
        }
        return max
    }
    const expensive = mostExpensive(array)
    document.write(`Most expensive price is ${expensive[1]} USD for ${expensive[0]}`);
</script>
<br>
<script>
    function mostCheap(array){
        let min = array[0]
        for (let jj = 1; jj < array.length; jj++){
            if (array[jj][1] < min[1]) min = array[jj];
        }
        return min
    }
    const cheapest = mostCheap(array)
    document.write(`Cheapest price is ${cheapest[1]} USD for ${cheapest[0]}`);
</script>

Upvotes: 1

Related Questions