13

I am using React's componentDidUpdate lifecycle method.

I am trying to determine whether or not two arrays are the same.

My prevState array looks like this:

prevState.players = [
  {
    name: 'Wayne Rooney',
    age: 31
  }, 
  {
    name: 'Lionel Messi',
    age: 29
  },
  {
    name: 'Robbie Fowler',
    age: 42
  }
];

and the this.state array looks like this:

this.state.players = [
  {
    name: 'Wayne Rooney',
    age: 31
  }, 
  {
    name: 'Lionel Messi',
    age: 29
  },
  {
    name: 'Robbie Fowler',
    age: 42
  }
];

As you can see if you expand the snippet below they are not equal:

let playersOne = [{
    name: 'Wayne Rooney',
    age: 31
  },
  {
    name: 'Lionel Messi',
    age: 29
  },
  {
    name: 'Robbie Fowler',
    age: 42
  }
];

let playersTwo = [{
    name: 'Wayne Rooney',
    age: 31
  },
  {
    name: 'Lionel Messi',
    age: 29
  },
  {
    name: 'Robbie Fowler',
    age: 42
  }
];

console.log(playersOne == playersTwo)

And here is my react lifecycle code.

  componentDidUpdate(prevProps, prevState) {
    if(prevState.players != this.state.players) {
      this.updatePlayers(this.state);
    }
  }

can anyone advise as to the best way to determine if the arrays are equal?

5
  • 2
    Duplicates stackoverflow.com/questions/201183/… and stackoverflow.com/questions/1068834/… Commented Feb 6, 2018 at 9:18
  • 4
    JSON.stringify(playersOne) == JSON.stringify(playersTwo) Commented Feb 6, 2018 at 9:19
  • @AkashDathan looks like that one will do it Commented Feb 6, 2018 at 9:20
  • One thing that React docs suggest is to use Immutable data since such comparisons can be expensive, but you still need to do it use _.isEqual from lodash or deep compare individual values Commented Feb 6, 2018 at 9:21
  • check all the results here Commented Feb 6, 2018 at 9:26

4 Answers 4

45

JSON.stringify(playersOne) == JSON.stringify(playersTwo)

Sign up to request clarification or add additional context in comments.

6 Comments

HAHAHAHA i love this
This will backfire if your objects contain cyclic references. the JSON.stringify() method will not work correctly.
This is also a bad idea if you care about the order of keys in an object.... JSON.stringify({a: 1, b: 2}) !== JSON.stringify({b: 2, a: 1});
@Adzz your example disproves your statement, did you mean "if you don't care about the order of keys" ?
Whoops, yea typo. If you think the two in the example should be equal, using JSON.stringify they would not be.
|
5
  1. Using _.isEqual from lodash;
  2. Using JSON.stringify and comparing the strings;

Comments

4

You can use array#every to check if both objects have the same number of objects and each object has the same number of key and values.

let playersOne = [{ name: 'Wayne Rooney', age: 31 }, { name: 'Lionel Messi', age: 29 }, { name: 'Robbie Fowler', age: 42 } ],
    playersTwo = [{ name: 'Wayne Rooney', age: 31 }, { name: 'Lionel Messi', age: 29 }, { name: 'Robbie Fowler', age: 42 } ];
 var isSame = playersOne.length === playersTwo.length && playersOne.every((o,i) => Object.keys(o).length === Object.keys(playersTwo[i]).length && Object.keys(o).every(k => o[k] === playersTwo[i][k]));
console.log(isSame);

1 Comment

Good, but I think it would be potentially a bit more efficient to use .some and !== in the lambda to check if either of the arrays is missing an element of the other.
4

You can use array.prototype.every :

var players = [
  { name: 'Wayne Rooney'  , age: 31 }, 
  { name: 'Lionel Messi'  , age: 29 },
  { name: 'Robbie Fowler' , age: 42 }
];

var statePlayers = [
  { name: 'Wayne Rooney'  , age: 31 }, 
  { name: 'Lionel Messi'  , age: 29 },
  { name: 'Robbie Fowler' , age: 42 }
];

var equals = players.length === statePlayers.length && players.every((e, i) => e.name === statePlayers[i].name && e.age === statePlayers[i].age);

console.log(equals);

Alternatively, using object destructuring and Array.prototype.some.

const
  players = [
    { name: 'Wayne Rooney'  , age: 31 }, 
    { name: 'Lionel Messi'  , age: 29 },
    { name: 'Robbie Fowler' , age: 42 }
  ],
  statePlayers = [
    { name: 'Wayne Rooney'  , age: 31 }, 
    { name: 'Lionel Messi'  , age: 29 },
    { name: 'Robbie Fowler' , age: 42 }
  ],
  playersEqual = (expected, actual) =>
    actual.length === expected.length &&
      !expected.some(({ name, age }, i) =>
        (({ name: otherName, age: otherAge }) =>
          name !== otherName || age !== otherAge)
        (actual[i]));

console.log(playersEqual(players, statePlayers));

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.