10

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?

peter flanagan
  • 6,130
  • 13
  • 50
  • 94
  • 2
    Duplicates https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects and https://stackoverflow.com/questions/1068834/object-comparison-in-javascript – Salman A Feb 06 '18 at 09:18
  • 4
    `JSON.stringify(playersOne) == JSON.stringify(playersTwo)` – Akash Dathan Feb 06 '18 at 09:19
  • @AkashDathan looks like that one will do it – peter flanagan Feb 06 '18 at 09: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 – Shubham Khatri Feb 06 '18 at 09:21
  • check all the results [**here**](https://www.google.co.in/search?q=how+to+check+two+arrays+of+objects+are+equal+in+javascript+site:stackoverflow.com&sa=X&ved=0ahUKEwib6IXV-5DZAhVDvY8KHdswDrkQrQIIMygEMAA&biw=1440&bih=803) – Mayank Shukla Feb 06 '18 at 09:26

4 Answers4

33

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

Akash Dathan
  • 3,468
  • 1
  • 21
  • 40
4
  1. Using _.isEqual from lodash;
  2. Using JSON.stringify and comparing the strings;
Bsalex
  • 2,457
  • 1
  • 12
  • 19
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);
Hassan Imam
  • 16,414
  • 3
  • 29
  • 41
  • 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. – Josh M. May 22 '20 at 12:50
3

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));
Mr. Polywhirl
  • 31,606
  • 11
  • 65
  • 114
Faly
  • 12,529
  • 1
  • 16
  • 34