0

I have the following function that makes absolutely no sense why it fails:

function GetPlayersMap ( map, id ){
    let compressedMap = [];
    for(let x = 0; x < map.length; x++){
        for(let y = 0; y < map[x].length; y++){
            if(map[x][y].claimant_id != null) {console.log(map[x][y].claimant_id); console.log(id)}
            if(id == null || map[x][y].claimant_id != id){
                map[x][y].count = null;
            }
            if(map[x][y].claimant_id != null){
                console.log(map[x][y]);
                compressedMap.push(map[x][y]);
            }
        }
    }
    return compressedMap;
}

map is a 2d array of objects, map.count is an int that is never null when entering the function. id is an int that can be null. The expected result is that on an id input of 0 it return a compressedMap with one object that matched that. The function is called twice, with the same map and an id of 0 then null. What is printed in console is

0
0
Tile { x: 0, y: 0, claimant_id: 0, count: null, fake_claimed: false }
0
null
Tile { x: 0, y: 0, claimant_id: 0, count: null, fake_claimed: false }

This is printed regardless of if I change the 5th line to

if(id == null){

(which makes no sense, this means it is matching 0 to null)or

if(map[x][y].claimant_id != id){

Only when I change it to

if(false){

do I get the expected output of

0
0
Tile { x: 0, y: 0, claimant_id: 0, count: 1, fake_claimed: false }
0
null
Tile { x: 0, y: 0, claimant_id: 0, count: 1, fake_claimed: false }

I added a simplified example of the code

class Tile {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.claimant_id = null;
    this.count = 1;
    this.fake_claimed = false;
  }
}

var map = []
for (let x = 0; x < 1000; x++) {
  map.push([]);
  for (let y = 0; y < 1000; y++) {
    map[x].push(new Tile(x, y));
  }
}
map[0][0].claimant_id = 0;

function GetPlayersMap(map, id) {
  let compressedMap = [];
  for (let x = 0; x < map.length; x++) {
    for (let y = 0; y < map[x].length; y++) {
      if (map[x][y].claimant_id != null) {
        console.log(map[x][y].claimant_id);
        console.log(id)
      }
      if (id == null || map[x][y].claimant_id != id) {
        map[x][y].count = null;
      }
      if (map[x][y].claimant_id != null) {
        console.log(map[x][y]);
        compressedMap.push(map[x][y]);
      }
    }
  }
  return compressedMap;
}

GetPlayersMap(map, 0);
GetPlayersMap(map, null);
GetPlayersMap(map, 0);
Aidan
  • 413
  • 3
  • 22
  • 4
    Best to always use `===` and `!==`, abstract equality comparison is too strange and unintuitive – CertainPerformance Dec 28 '19 at 21:06
  • Tried that, unfortunately no luck – Aidan Dec 28 '19 at 21:08
  • 4
    Can you provide a [mcve] that accurately reproduces the behaviour? I can't quite see what's wrong just by looking at he code - I'm not sure which console.log is executed when. – VLAZ Dec 28 '19 at 21:09
  • 1
    I'm not saying it'll solve the problem, I'm saying that it makes code *much* easier to understand at a glance – CertainPerformance Dec 28 '19 at 21:09
  • I believe the whole project is the minimal reproducible example, I attempted to simplify it, but that returns the expected result. – Aidan Dec 28 '19 at 21:26
  • try using node debugger, also knowing node version would be helpful –  Dec 28 '19 at 21:29
  • @ishidex2 node v10.16.3, and I'll try it thanks – Aidan Dec 28 '19 at 21:30
  • Running the example in the code snippet, it behaves exactly as I'd expect - the first tile has a count of 1, the second has a count of null. The second is null because we passed in an id of null, obviously. – Hecksa Dec 28 '19 at 21:48
  • @Hecksa yeah, it returns the expected result, that is where my issue comes in, it doesn't when actually used in project – Aidan Dec 28 '19 at 21:59
  • No, the logging is merely for debugging – Aidan Dec 28 '19 at 22:03
  • it's confusing me like hell, what is what so should the second function return something or just not find something? Maybe you want to edit id to searchVal or something – fubar Dec 28 '19 at 22:05
  • @fubar I am confused as to what you are asking – Aidan Dec 28 '19 at 22:07
  • if i get this correctly you are asking why `map[x][y].claimant_id != null` and `id == null` are interchangable on line five of the first code snippet? – fubar Dec 28 '19 at 22:12

1 Answers1

1

map.count is an int that is never null when entering the function.

I kindly disagree with that statement since because you don't copy the array or the objects nested inside so that map[x][y].count = null; will edit the array/object permanent. This might lead to the impresiion that null==0 though the code was never executed in that call.

Below the code with a deep-copy. Does this answer your question?

Since you have allot of data, I assume give the post about deep-copy a read.

class Tile {
    constructor(x, y) {
      this.x = x;
      this.y = y;
      this.claimant_id = null;
      this.count = 1;
      this.fake_claimed = false;
    }
}
  
  var map = []
  for (let x = 0; x < 10; x++) {
    map.push([]);
    for (let y = 0; y < 10; y++) {
      map[x].push(new Tile(x, y));
    }
  }
  map[0][0].claimant_id = 0;
  
  function GetPlayersMap(map, id) {

    // added copy of array
    const copy = JSON.parse(JSON.stringify(map));

    let compressedMap = [];

    for (let x = 0; x < copy.length; x++) {
      for (let y = 0; y < copy[x].length; y++) {

        if (id == null || copy[x][y].claimant_id != id) {
          copy[x][y].count = null;

        }
        if (copy[x][y].claimant_id != null) {
          console.log(copy[x][y]);
          compressedMap.push(copy[x][y]);

        }
      }
    }
    return compressedMap;
  }
  
  GetPlayersMap(map, 0);
  GetPlayersMap(map, null);
  GetPlayersMap(map, 0);
fubar
  • 383
  • 2
  • 11
  • Yep that fixed it, I thought the function call was copying the array, I see my mistake now. – Aidan Dec 29 '19 at 01:25