Finding value in multidimensional array

I created a multidimensional array with radiators, and some information about them, such as the dimensions and the price (which is the 5th item).

const radiators = [
  [3,	300,	20,	"name1",	550],
  [2,	300,	30,	"name2",	450],
  [2,	200,	50,	"name3",	480],
  [2,	200,	30,	"name5",	480] 
];

I then created a function which writes the price of the radiator which corresponds with the value of three dropdown menus:

function WritePrice() {
  let SelectedRadiator = radiators.find(
    item => (
      item[0] == document.getElementById("Dropdown1").value && 
      item[1] == document.getElementById("Dropdown2").value &&
      item[2] == document.getElementById("Dropdown3").value
    )
  );
  document.getElementById("Price").innerHTML = SelectedRadiator[4];
}

However, when I run this, I get the following error:
Uncaught TypeError TypeError: Cannot read properties of undefined (reading ‘4’)

The error refers to my last line: document.getElementById(“Price”).innerHTML = SelectedRadiator[4];

What do I do wrong?

1 Like

Hint: What do you do if SelectedRadiator is undefined?

(More than likely, you’ve managed to create an array of dropdown choices that corresponds to NONE of your radiators. Imagine what happens if your dropdowns are set to 3, 200, 50.)

1 Like

Dear Hutley

No, that is not the issue. I created code to make sure that the drop-downs can only select actually existing radiators from the table. The real table is much longer.

Kind regards

1 Like

Well, what your error is telling you is that SelectedRadiator is undefined.

Without seeing the full table and/or dropdowns, I cant give a more descriptive answer of your problem. I can only work with what I’ve got.

1 Like

You will get that error if find() does not find an element in the array that satisfies the testing function WritePrice().

In other words make sure the three dropdown values selected are valid for one of the array elements. So for example 2, 300, 30 would be be OK; but 2, 300, 50 would give that error.

You could check whether SelectedRadiator is undefined:

if(SelectedRadiator) document.getElementById("Price").innerHTML = SelectedRadiator[4]
else document.getElementById("Price").innerHTML = "No radiator found";

But it’s probably better to arrange the dropdowns so only valid options can be selected.

1 Like

Hello,

The the of you were right. There was an issue with the dropdown values. It works now. Thanks a million! :slight_smile:

You should really think about using an array of objects for your radiators.

const myRadiators =
[
    {
        "id" : 1,
        "count",
        "width" : 300,
        "height" : 50,
        "price" : 100
       …
    },
    {
        …
    }
];
1 Like

@myDeveloper ,

For future reference to format your code, select your code in the text editor and click on the </> option in the top menu.

You will see I have also reformatted your WritePrice function by breaking it up into multiple lines. It makes it more readable.


Just to add Thallius makes a valid point.

What happens when you return to this code in the future. Is the following going to make sense to you?

[3,	300,	20,	"name1",	550] 

I had a look at various pages on radiators, and apart from possibly height and price I can’t figure out what those figures correspond to.

Hello,

The problem is that the final code will have 200 radiators, with each multiple fields

  • height
  • width
  • number of blades
  • type
  • code
  • price
  • capacity (Watt)

What would the shortest way to maintain this list?

1 Like

One option is to maintain the list of radiators using a spreadsheet: for example using LibreOffice Calc.Then export the data to a CSV format file. After uploading that file to your server, use JavaScript to read the file using fetch() and use split() to create the multi-dimensional array or JavaScript object.

Personally I would add a JavaScript comment to describe the array items rather than use an object.

If going down that route, wouldn’t JSON be a possibility too?

Wouldn’t destructuring be a better option than comments?

const [width, height, blades] = radiator

I don’t see the issue with using an array of object data, but maybe I am missing something.

1 Like

LibreOffice Calc does not export/save JSON. I don’t know about Microsoft Excel.

That’s certainly an option but you can put what you want in a comment :grinning:.

It’s personal choice. I don’t see that you really gain much by using an array of objects instead of an array of arrays. I guess processing time is quicker with arrays but it’s very unlikely to be significant.

Not my area of expertise but I tested an online CSV to JSON converter and it seems to do a decent job. Which is why I did ask the question.

I confess I am suffering with a bit of brain fog right now, but readability? Surely being able to access the data by key names, ‘width’, ‘height’ etc rather than working with index numbers makes sense. Using comments , just doesn’t seem best practice to me, but maybe I am over complicating things.

You do not see the advantage of

const volume = myRadiators.width * myRaditors.height * myRadiators.depth; 

Against

const volume = myRadiators[3] * myRadiators[4] * myRadiators[5];

?

I can’t believe…

In my view this is simple and adequately readable:

fetch(url)
  .then(response => response.text())
    .then(text => {
      lines = text.split("\n");  // array of CSV lines (first string may be column headings)
    });
	
function WritePrice() {
let SelectedRadiator = lines.find( (line) => (
  line.split(",")[0]    == document.getElementById("heightDropdown").value
  && line.split(",")[1] == document.getElementById("widthDropdown" ).value
  && line.split(",")[2] == document.getElementById("bladesDropdown").value
));

if(SelectedRadiator) document.getElementById("Price").innerHTML = SelectedRadiator.split(",")[4]
else document.getElementById("Price").innerHTML = "No radiator found";
}

Of course you could add more comments.

(Note: code needs to handle any error on reading CSV file)

Use of an online CSV to JSON converter is not necessary.

And then someone inserts a column in the excel file and all your code does no longer work….

I hate such static things relying on fix excel sheet.

I would go much further and not even read a csv but the excel itself and check the column headers values. Yes, this is much more work, but you can never ever trust on a standard excel user to understand the need of not changing column orders, not enter second title row etc.

I know this from many years of experience on importing excel data …

That’s fair comment. Your approach would cope with changes to the spreadsheet columns provided the text heading each column remains as expected. Both approaches would need to check whether the data appears valid and if necessary give an error message to website visitors.

For my approach a simple initial check would to be to ensure the first line of the CSV file starts with “Height,Width,Blades,Type,Price”. A second title row would not be an issue.

To find a specific value in a multidimensional array, you can iterate through its nested arrays using loops. For example, in JavaScript:
const multidimensionalArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];

const targetValue = 5;

let found = false;

for (let i = 0; i < multidimensionalArray.length; i++) {
for (let j = 0; j < multidimensionalArray[i].length; j++) {
if (multidimensionalArray[i][j] === targetValue) {
found = true;
break;
}
}
if (found) {
break;
}
}

if (found) {
console.log(Value ${targetValue} found in the array.);
} else {
console.log(Value ${targetValue} not found in the array.);
}