Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React useEffect() : Most efficient way to compare if two arrays of objects are equal

I have a useEffect() that should trigger when an array of objects changes.

  useEffect(() => {
    setNotesToRender(props.notes)
  }, [props.notes]);

The useEffect dependency cannot compare arrays of objects, so the useEffect() in the example above triggers more often than needed. I only wish to trigger the useEffect() when the arrays differ.

An example of arrays that should trigger update

array1 = [{id:1,title:'one'},{id:2,title:'two'},{id:3,title:'three'}]
array2 = [{id:1,title:'one'},{id:2,title:'two'},{id:3,title:'four'}]

Things I have tested so far are:

  1. props.notes.length --> works but is not reliable - for obvious reasons :)
  2. ...props.notes --> does not work if array is empty - and may cause serious performance issues?

What is the most efficient way to compare two arrays of objects? The arrays may contain over 1000 objects.

Kind regards /K

UPDATE I need to filter out certain "notes" later using a text search, that's why I am using a React state. This is not shown in my example code.

like image 465
Kermit Avatar asked Oct 18 '25 13:10

Kermit


1 Answers

What is the most efficient way

The most efficient way is likely a custom compare for this particular shape of data. You could use JSON.stringify or some other generic comparing function, but it's not likely to be the most efficient for obvious reasons.

So in your example a simple compare function might look like ->

const array1 = [{id:1,title:'one'},{id:2,title:'two'},{id:3,title:'three'}];
const array2 = [{id:1,title:'one'},{id:2,title:'two'},{id:3,title:'four'}];

const arrayIsEqual = (a1, a2) => 
  a1 === a2 ||
  a1.length === a2.length &&
  a1.every((f,i) => 
    f.id === a2[i].id &&
    f.title === a2[i].title
  )
  
  
//tests
const a1clone = [...array1];

//different arrays not equal
console.log(arrayIsEqual(array1, array2)); //false

//different arrays equal
console.log(arrayIsEqual(array1, a1clone)); //true

//different arrays same values, but different order
a1clone.reverse();
console.log(arrayIsEqual(array1, a1clone)); //false

//same arrays, fastest check
console.log(arrayIsEqual(array1, array1)); //true
like image 150
Keith Avatar answered Oct 21 '25 02:10

Keith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!