0

I am trying to create a script in which it is needed to check if an object is already in an array, but am having difficulties.

Here is what i am trying to do:

var boardTiles = [{"id":70,"color":"y","number":11,"owner":"0","locked":false}];
var usedTiles = [{"id":42,"color":"y","number":"11"}];

var playableFields = [];

for (var i = 0; i < boardTiles.length; i++){
    if(boardTiles[i].owner === "0" && boardTiles[i].number !== 13){

        var thisTileJson = {
            "color": boardTiles[i].color,
            "number": ""+boardTiles[i].number
        };

        playableFields.push(thisTileJson);
    } 
}

for (var i = 0; i < usedTiles.length; i++){

    var checkThis = false;

    var thisUsedTileJson = {
        "color": usedTiles[i].color,
        "number": ""+usedTiles[i].number
    };

    console.log("ThisUsedTile: "+JSON.stringify(thisUsedTileJson)); 
    console.log("ThisplayableField: "+JSON.stringify(playableFields[i]));      
    console.log("Is object in array:" +containsObject(thisUsedTileJson, playableFields));
}

function containsObject(obj, list) {
    var i;
    for (i = 0; i < list.length; i++) {
        if (list[i] === obj) {
            return true;
        }
    }

    return false;

}

I thinks that I should be getting a "true" from the containsObject function but am getting a false?

My console.log looks like this:

ThisUsedTile: {"color":"y","number":"11"} VM1123:29 ThisplayableField: {"color":"y","number":"11"} VM1123:30 Is object in array: false

I really am in the dark and hoping for help.

Thanks in advance :-)

Mansa
  • 2,277
  • 10
  • 37
  • 67
  • You can probably get rid of the entire `containsObject` function and just replace it with `if(list[i] in obj)` – Scott Marcus Feb 18 '17 at 16:08
  • @Alexandru-Ionut Mihai The property order is not guaranteed when using JSON.stringify. So it might return false just because the keys were in a different order – baao Feb 18 '17 at 16:10
  • object equality is by reference, so two different objects - even with same elements will be false. `{a:1} != {a:1}` You need check each individual field – Simon H Feb 18 '17 at 16:11
  • 1
    @Alexandru-Ionut Mihai - I didn't downvote your answer, but re your asking why other people did: Using `JSON.stringify` to compare objects is a *terrible* idea. It's slow, it leaves out differences (like a property that doesn't exist vs. a property that exists with the value `undefined`), and it has false negatives: `{foo:1,bar:2}` and `{bar:2,foo:1}` will be unequal based on a JSON.stringify check, whereas by a reasonable definition of equivalence (same properties with same values), they're equivalent. – T.J. Crowder Feb 18 '17 at 16:11
  • @baao: Actually, the order that `JSON.stringify` will render the properties *is* guaranteed, as of ES2015. Assuming an ordinary object, the order is defined [here](http://www.ecma-international.org/ecma-262/7.0/index.html#sec-ordinaryownpropertykeys). Which, combined with how object initializers work, is why `{foo:1,bar:2}` and `{bar:2,foo:1}` will return *different* JSON strings. – T.J. Crowder Feb 18 '17 at 16:14
  • @T.J.Crowder wow, thank you for the clarification, didn't know that. – baao Feb 18 '17 at 16:17
  • 1
    So, I guess the answer here is: if (list[i].color === obj.color && list[i].number === obj.number) - That seems to work :-) Any hidden downfalls in this? – Mansa Feb 18 '17 at 16:21
  • @Mansa: Nope, that's just fine, if those are the only two properties that need to match. ;-) – T.J. Crowder Feb 18 '17 at 16:21
  • Perfect :-) - Thanks – Mansa Feb 18 '17 at 16:24

0 Answers0