简体   繁体   中英

Comparing Object.values array not working

So I am making a tic-tac-toe game. This array is all the possible win conditions.

let array = [
  {box1: "empty", box2: "empty", box3: "empty"},
  {box1: "empty", box4: "empty", box7: "empty"},
  {box1: "empty", box5: "empty", box9: "empty"},
  {box2: "empty", box5: "empty", box8: "emtpy"},
  {box3: "emtpy", box6: "emtpy", box9: "empty"},
  {box3: "empty", box5: "empty", box7: "empty"},
  {box4: "empty", box5: "empty", box6: "emtpy"},
  {box7: "emtpy", box8: "empty", box9: "emtpy"}
];

This next bit of code is being used to check if a win condition was met.

for(let i = 0; i < array.length; i++){
    if(Object.values(array[i]) === "o","o","o"){
      console.log('o won');
    } else if (Object.values(array[i]) === "x","x","x"){
      console.log('x won');
    } else if (Object.values(array[i]) === "empty","empty","empty"){
      console.log('works as expected');
    } else {
      console.log('total fail');
    }
}

When you run this you will find that "o won" is logged. I am so confused about why it does this. Object.values returns an array. When I compare those values using strictly equals it still appears to be checking if each value is a string rather than comparing the actual strings.

Your code is using the comma operator which evaluates each of its operands from left to right and returns the last operand. In the line below, the last operand is "o", a non-empty string, which is true when implicitly converted to a boolean. This expression therefore will always be true:

if(Object.values(array[i]) === "o","o","o"){

Comma operator: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

To determine whether two arrays are equal, you can use a function like:

function arraysEqual(a, b) {
    return a.length == b.length && a.every(function(element, index) {
        return element === b[index];
    });
}

if (arraysEqual(myArray, ['x', 'x', 'x'])) {
    // they're equal
}

You can't chain equality comparison like that - you should test each individual value explicitly, like so:

 const arrayItem = {box1: "o", box2: "o", box3: "o"} if(Object.values(arrayItem).every(item => item === "o")) console.log('o wins'); 

Arrays (objects) reference memory locations, and objects are only considered equal if they reference the same place in memory, so even if the syntax was right, you wouldn't be able to do what you seem to have been trying to do:

if(Object.values(array[i]) === ["o","o","o"])

because the newly created ["o","o","o"] doesn't reference the same object as the one in the array variable.

Use brackets for your rows.

for(let i = 0; i < array.length; i++){
    if(Object.values(array[i]) === ["o","o","o"]){
      console.log('o won');
    } else if (Object.values(array[i]) === ["x","x","x"]){
      console.log('x won');
    } else if (Object.values(array[i]) === ["empty","empty","empty"]){
      console.log('works as expected');
    } else {
      console.log('total fail');
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM