0

I have to compare two big arrays of objects in react componentwillreceiveprops. I have array of 261 countries. For example it begins from this.

 countries = [
     {id: 1, name: "Australia", code: "AU", isRemoved: false}
      ...
      261 objects
 ]

I must compare that the array that will be received in next props is absolute identical with my current countries array, that is all properties, length, property values, all things are equal. Please help me. I wrote something like this, but I know just !== not correct.

if (this.state.countriesInitial !== countries) {//TODO: compare arrays
      this.setState({
          countriesInitial: countries
      })
}

Any answers will be taken into acccount. Maybe lodash has some methods that will simplify the task, i dont know. Any answers will be considered. Thanks in advance.

jo_va
  • 13,504
  • 3
  • 23
  • 47
Dragon14
  • 317
  • 6
  • 18

5 Answers5

1

Yes, lodash has a method that makes life easier - _.isEqual():

var arr1 = [ /* Very long array */ ],
    arr2 = [ /* Also long array */ ];
var equalArrays = _.isEqual(arr1, arr2);

Alternatively, use JSON methods:

var arr1 = [ /* Very long array */ ],
    arr2 = [ /* Also long array */ ];
var equalArrays = JSON.stringify(arr1) == JSON.stringify(arr2);
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
  • Thanks for your answer. I wanna ask: does lodash compare arrays of objects or just arrays? I wanted to test it but I don't know does codepen or jsfiddle support lodash? which online editor supports lodash? – Dragon14 Mar 01 '19 at 03:16
  • Just tested it on jsfiddle, both methods work. Thanks. – Dragon14 Mar 01 '19 at 03:55
  • No problem @Dragon14, always glad to help. – Jack Bashford Mar 01 '19 at 03:56
  • Hi Jack. Can you help me with my question? https://stackoverflow.com/questions/57652942/how-to-understand-this-fragment-of-code-in-javascript-react – Dragon14 Aug 26 '19 at 06:59
0

You can stringify the arrays and compare the strings

const arr1 = [
  {
    id:1,
    name: 'Australia'
  },
  {
    id:2,
    name: 'Greece'
  }
];

const arr2 = [
  {
    id:1,
    name: 'Australia'
  },
  {
    id:2,
    name: 'Greece'
  }
];

function arraysEqual(arr1, arr2) {
  return JSON.stringify(arr1) === JSON.stringify(arr2);
}

const compare = arraysEqual(arr1, arr2);
console.log(compare);
kapantzak
  • 11,610
  • 4
  • 39
  • 61
0

If I understand your question, you're trying to see if two arrays of objects are equal to each other. One way you can do this in vanilla JS is by using JSON.stringify():

const countries = [{id: 1, name: "Australia", code: "AU", isRemoved: false}],
nextProp = [{id: 1, name: "Australia", code: "AU", isRemoved: false}],

checkEq = (arr, arr2) =>
    JSON.stringify(arr) === JSON.stringify(arr2)

console.log(checkEq(countries, nextProp)); // true
console.log(checkEq([{a: 1}], [{a: 1}, {b: 2}])); // false
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
0

Arrays are reference types, so comparing them will simply compare their references and not their content.

A quick way (programmatically) to compare the content of your arrays is to stringify them with JSON.stringify() and compare the resulting strings:

const arr1 = [
  {id: 1, name: "Australia", code: "AU", isRemoved: false},
  {id: 2, name: "France", code: "FR", isRemoved: false}
];
const arr2 = [
  {id: 1, name: "Australia", code: "AU", isRemoved: false},
  {id: 2, name: "France", code: "FR", isRemoved: false}
];
const arr3 = [
  {id: 1, name: "Austria", code: "AS", isRemoved: false},
  {id: 2, name: "France", code: "FR", isRemoved: false}
];

console.log(JSON.stringify(arr1) === JSON.stringify(arr2));
console.log(JSON.stringify(arr1) === JSON.stringify(arr3));

Or a faster method than stringifying the whole arrays, is to first compare the lenghts and if they match to compare every entries using Object.entries() and Array.every().

This will work if the fields of your entries are primitive types (not arrays nor objects), otherwise you will need a recursive version of this:

const sameEntries = (x, y) => {
  const xEntries = Object.entries(x);
  if (xEntries.length !== Object.entries(y).length) return false;
  return xEntries.every(([k,v]) => y[k] === v);
}

const sameArrays = (arr1, arr2) =>
  arr1.length === arr2.length && arr1.every((x, i) => sameEntries(x, arr2[i]));

const arr1 = [
  {id: 1, name: "Australia", code: "AU", isRemoved: false},
  {id: 2, name: "France", code: "FR", isRemoved: false}
];
const arr2 = [
  {id: 1, name: "Australia", code: "AU", isRemoved: false},
  {id: 2, name: "France", code: "FR", isRemoved: false}
];
const arr3 = [
  {id: 1, name: "Austria", code: "AS", isRemoved: false},
  {id: 2, name: "France", code: "FR", isRemoved: false}
];

console.log(sameArrays(arr1, arr2));
console.log(sameArrays(arr1, arr3));
jo_va
  • 13,504
  • 3
  • 23
  • 47
0

there are several options, you get few of them here, but if you wanna do it in pure JS you can use the filter, I give you an example here, maybe it helps.

we have an array named companies:

const companies = [
    {name: "blueweb360", category: "internet", start: 2013, end: 2014},
    {name: "Himo", category: "internet", start: 2015, end: 2016},
    {name: "blue", category: "IOT", start: 2014, end: 2017},
    {name: "waac", category: "Tech", start: 2016, end: 2019}

];

and now we need to get companies which have category equal to the internet:

const retail = companies.filter(iterator => iterator.category == "internet")

document.write(JSON.stringify(retail)) //or you can write console.log(retail)

with filter just by using or(||) and, and(&&) you can write multiple conditions. filter is JS ES6 method and good for problem like that.

Pooya Panahandeh
  • 578
  • 7
  • 21