.findIndex keeps returning -1

I have an object of the form myarray[“foo”][n], myarray[“bar”][n], etc… where n is a normal integer key.

For a given value x, I need to find the value of n such that myarray[“foo”][n] = x so that I can retrieve the matching myarray[“bar”][n] value.

I had googled a little bit and found that findIndex is the way to do this, however it is a method of Array, not Object, and I already found out the hard way that myarray is not an array but an object (found this out earlier trying to use myarray[“foo”].length, ended up having to use Object.keys(myarray[“foo”]).length, which works).

I tried using Object.keys(myarray[“foo”].findIndex(s => s == x) and it returned a value of -1 for situations where I’m able to verify via other methods (like reading the data it comes from) that it should not have returned -1.

Object.keys will return the keys of the object rather than the values, so you won’t find your “x” value in there. Can you show us an example of the object you’re working on?

It is the key that I want, though. I need to know which key contains the value x I’m given.

But I came up with a workaround that seems to work fine:

for(i=0;i<Object.keys(myarray["foo"]).length;i++)
{
  if(myarray["foo"][i] == x)
  {
    return myarray["bar"][i];
  }
}

This searches myarray[“foo”] for the value i such that myarray[“foo”][i] = x, and then returns the matching value of myarray[“bar”][i].

OP, please post a sample of your array (NOT a print_r output) and the data you want out of it.

Alright. I simplified the code in the previous example because I’m not sure I can make it clear what the code is aiming to do without pasting pages of code. Here is an abridged version.

It starts with PHP getting the mySQL table contents, and showing that code is probably the best way to explain what keys the array has:

function load_terrain_contents()
{
  global $db;
  $map_list = $db->prepare('SELECT * FROM terrain_contents');
  $map_list->execute();
  $listcounter=1;
  foreach($map_list as $terrain)
  {
    $list['Terrain'][$listcounter] = (int) $terrain['Terrain'];
    $list['Nothing'][$listcounter] = (int) $terrain['Nothing'];
    $list['Settlement'][$listcounter] = (int) $terrain['Settlement'];
    $list['Cave'][$listcounter] = (int) $terrain['Cave'];
    $list['Graveyard'][$listcounter] = (int) $terrain['Graveyard'];
    $list['Fortress'][$listcounter] = (int) $terrain['Fortress'];
    $list['Tower'][$listcounter] = (int) $terrain['Tower'];
    $list['Temple'][$listcounter] = (int) $terrain['Temple'];
    $list['Mine'][$listcounter] = (int) $terrain['Mine'];
    $list['Ruin'][$listcounter] = (int) $terrain['Ruin'];
    $listcounter++;
  }
  $map_list->closeCursor();
}

Then in the file for the webpage near the top it has a couple lines (omitting non-relevant lines here) that convert this to a javascript array (except that I think it becomes an Object due to the source array being mulltidimensional):

$terrain_contents = load_terrain_contents();
$js_array = json_encode($terrain_contents);
echo ("var terrain_contents = ".$js_array.";\n";

Later on in the webpage file’s long SCRIPT block in the HEAD… As I mentioned in the previous code, I found a workaround so there is no use of findIndex anymore.

var i;
var j;
var contents = [];
contents["key"] = [];
contents["weight"] = [];
for(i=0;i<Object.keys(terrain_contents).length-1;i++) // -1 because skipping the ['Terrain'] key itself
{
  contents["key"][i] = i+1;
  for(j=0;j<Object.keys(terrain_contents["Terrain"]).length;j++)
  {
    if(terrain_contents["Terrain"][j+1] == document.getElementById("test_tile_value").value)
    {
      contents["weight"][i] = terrain_contents[getContentsfromIndex(i+1)][j+1];
    }
  }
}

If I had been able to use fileIndex the way I wanted, I would have been able to avoid nested for loops there.

Please provide an SQL dump of your db with sample records and a description of what you are wanting to know about this data.

Additionally, why are you json encoding the data?

I’m using json_encode because my understanding (based on google searching years ago) is that this is how to make a php array usable in javascript.

I don’t know how to do an “SQL dump”, but I’m not really sure what the point of that would be now. As I already mentioned, I have an alternate solution that works.

This is probably the best solution for your data structure.

I didn’t realize you just wanted something that “works”. Usually when people come here they want to learn the best/correct way to do something.

Going off the PHP function you’ve provided above, it looks like you have a grid of terrain of different types and you want to get the properties of each tile from a lookup, based on its type. Is that right?

Not quite, in this case it’s actually a different type of 2D array… the type of terrain, and a set of probability weights related to things that can appear on that type of terrain. I haven’t even gotten to the grid yet, and that’s going to be kind of a nightmare since it’s a hexagonal grid instead of a square grid.

Hexagonal grids aren’t as scary as they first appear, as long as you start right. This gives a good overview of them.

I’d look at working this the other way around; key your terrain types by their ids, and have your grid populated with those ids. As pseudocode:

terrain = {
    1: { type: 'plain', chancesOf: [ { item: 'cave', chance: 0.1 }, { item: 'ruin', chance: 0.2 }, ... ] },
    ...
};

So 1 is the terrain type: that’s what you save in your eventual grid. type is the key of the terrain type; you might not even need that. chancesOf is a list of “things” and the chances of their appearing. As you add more mechanics you can add other values to the object; defensive bonuses, income every turn, whatever your game requires.

Now all you need to do when you see a terrain ID is go and get terrain[terrain ID] to find all the information about that terrain type.

Yeah, I was looking into a method that is very much like one of the ones on that page, although that page solves some of the confusion I had.

Anyway, thanks a lot for the assistance here. I can’t seem to see how to mark this as “solved” (not sure if this forum does that, a lot of other help forums do).

Sponsor our Newsletter | Privacy Policy | Terms of Service