Search code examples
javascriptarraysdata-structurescomparisonequality

Javascript - Check if arrays within an array are the same


Whats the best way to check if the arrays within an array are the same in my case?

var arrSession = [
  {
    type: '1',
    usecase: [ '1' ]
  },
  {
    type: '1',
    usecase: [ '1' ]
  }
];

var checkUsecase = arrSession.every(isSame);

function isSame(obj, index, arr) {
    if (index === 0) {
        return true;
    } else {
        return (
            (obj.type === arr[index - 1].type) &&
            (obj.usecase === arr[index - 1].usecase)
        );
    }
}

console.log('checkUsecase:');
console.log(checkUsecase);

The 'usecase' object within the array use to be a string '' and the isSame function used to work. But now they are arrays too. How to change the isSame function?

Here is a fiddle: https://jsfiddle.net/3j0odpec/


Solution

  • This answer too chooses the already proposed every based comparison approach ...

    const isFullItemEquality = arrSession
      .every((item, idx, arr) =>
        idx === 0 || isDeepDataStructureEquality(item, arr[idx - 1])
      );
    

    ... only that it does not utilize JSON.stringify.

    For sameness / equality comparison of JSON conform data structures where performance is important as well, one might consider going with the following recursive implementation of isDeepDataStructureEquality ...

    <script>
      // implemented by Peter Seliger
      function isDeepDataStructureEquality(a, b) {
        let isEqual = Object.is(a, b);
    
        if (!isEqual) {
          if (Array.isArray(a) && Array.isArray(b)) {
    
            isEqual = (a.length === b.length) && a.every(
              (item, idx) => isDeepDataStructureEquality(item, b[idx])
            );
          } else if (
            a && b
            && (typeof a === 'object')
            && (typeof b === 'object')
          ) {
            const aKeys = Object.keys(a);
            const bKeys = Object.keys(b);
    
            isEqual = (aKeys.length === bKeys.length) && aKeys.every(
              (key, idx) => isDeepDataStructureEquality(a[key], b[key])
            );
          }
        }
        return isEqual;
      }
    </script>
    <script>
      // implemented by Alexander Nenashev
      function isSame(a, b) {
    
        const iterator = Array.isArray(a) && Array.isArray(b) ? a.keys() : 
        (typeof a === 'object') && (typeof b === 'object') ? Object.keys(a) : null;
    
        if (iterator) {
            for (const i of iterator) {
                if (!isSame(a[i], b[i])) {
                    return false;
                }
            }
            return true;
        }
    
        return a === b;
    
      }
    </script>
    <script benchmark data-count="10">
    
      const arrSession = JSON.parse(JSON.stringify(Array
        .from({ length: 300000 })
        .reduce(arr => arr.push(...[{
          type: '1',
          usecase: ['1'],
          child: {
            type: '1',
            usecase: ['1'],
            child: {
              type: '1',
              usecase: ['1'],
              child: {
                type: '1',
                usecase: ['1'],
              },
            },
          },
          child: {
            type: '1',
            usecase: ['1'],
          }
        }]) && arr, [])));
    
        // countercheck implementations with an unequal data structure.
        // arrSession.at(-1).child.usecase[0] = 0;
    
        // @benchmark JSON.stringify
        arrSession.every((item, idx, arr) =>
          idx === 0 || JSON.stringify(item) === JSON.stringify(arr[idx - 1])
        );
        // @benchmark recursive isSame
        arrSession.every((item, idx, arr) =>
          idx === 0 || isSame(item, arr[idx - 1])
        );
        // @benchmark recursive isDeepDataStructureEquality
        arrSession.every((item, idx, arr) =>
          idx === 0 || isDeepDataStructureEquality(item, arr[idx - 1])
        );
    </script>
    <script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>