最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Compare unsorted arrays of objects in Javascript - Stack Overflow

programmeradmin4浏览0评论

I have to pare two unsorted arrays of objects, for example the following code should return true:

pareObjs(
    [{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }], 
    [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }]
)

I know there are already plenty of answers about paring arrays of objects, but I did not really find the clear one for paring the unsorted version of arrays.

I have to pare two unsorted arrays of objects, for example the following code should return true:

pareObjs(
    [{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }], 
    [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }]
)

I know there are already plenty of answers about paring arrays of objects, but I did not really find the clear one for paring the unsorted version of arrays.

Share Improve this question asked Dec 1, 2017 at 8:21 ShotaShota 7,3609 gold badges39 silver badges73 bronze badges 7
  • 2 function pareObjs() { return true } will do that. Why do you expect it to return true, and when should it not? – Bergi Commented Dec 1, 2017 at 8:23
  • 1 I expect it to be true because the length of both arrays are the same and they contain the same objects (same keys and values). Object references do not matter in this case. – Shota Commented Dec 1, 2017 at 8:24
  • Several questions on here asks the same. Check out: stackoverflow./questions/9191791/… and stackoverflow./questions/201183/… – xpqz Commented Dec 1, 2017 at 8:26
  • 1 @Shota Could you just sort them? – Bergi Commented Dec 1, 2017 at 8:28
  • I've read that answers, but JSON.stringify won't work, as the arrays are not sorted and I cant use lodash, I have to do this in Vanilla JS – Shota Commented Dec 1, 2017 at 8:28
 |  Show 2 more ments

6 Answers 6

Reset to default 2

Here another possibility:

const array2 = [1,3,2,4,5];

const isInArray1 = array1.every(item => array2.find(item2 => item===item2))
const isInArray2 = array2.every(item => array1.find(item2 => item===item2))

const isSameArray = array1.length === array2.length && isInArray1 && isInArray2

console.log(isSameArray); //true

function givemeSanitizedObject(arr1) {
  let obj = {}
  arr1.forEach(function(element, index, array) {
      obj = {
        ...obj,
        ...element,
      }
  })
  return obj
 }

 function pareObjs(arr1, arr2) {
    let obj1 = givemeSanitizedObject(arr1)
    let obj2 = givemeSanitizedObject(arr2)

    for (var property in obj1) {
      if (Object.hasOwnProperty(property)) {
        if (obj1.property !== obj2.property) {
          return false
        }
      }
    }
    return true
}

console.log(pareObjs(
  [{
    foo: 'foo',
    bar: 'bar'
  }, {
    baz: 'baz'
  }], [{
    baz: 'baz'
  }, {
    foo: 'foo',
    bar: 'bar'
  }]
))

You could convert each object to string using JSON.stringify(). Then sort these arrays. And pare each pair.

If you dont't mind about es6:

let arr1 = [{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }];
let arr2 = [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }];

const Compare = (arr1, arr2) => {
  if (arr1.length != arr2.length) {
    return false
  }

  let a1 = arr1.map(e => JSON.stringify(e)).sort()
  let a2 = arr2.map(e => JSON.stringify(e)).sort()
  
  return !a1.map((e, i) => e == a2[i]).includes(false)
}

console.log(Compare(arr1, arr2))

A basic approach will be to loop through all the objects of one of the arrays and see if you can find similar objects in the other array.

Here is an example:

function pareArrays(arr1, arr2){
    if(arr1.length != arr2.length){
        return false;
    }

    for(var i = 0; i < arr1.length; i++){
        var value1 = arr1[i];
        var keys1 = Object.keys(value1);
        var found = false;
        for(var j = 0; j < arr2.length; j++){
           var value2 = arr2[j];
           var keys2 = Object.keys(value2);
           if(keys1.length == keys2.length 
              && keys1.every(k => keys2.includes(k)) 
              && keys1.every(k => value1[k] == value2[k])){
              found = true;
              break;
           }
        }
        if(!found){
           return false;
        }
    }
   
    return true;
}

var p = pareArrays(
    [{ foo: 'foo', bar: 'bar' }, { baz: 'baz'}], 
    [{ baz: 'baz' }, { foo: 'foo', bar: 'bar'}]
);

console.log(p);

You could use a hash table and check if the proprties and values are the same. It works with the given types.

function pareArrays(array1, array2) {
    var hash = {};

    if (array1.length !== array2.length) {
        return false;
    }

    array1.forEach(function (o) {
        var keys = Object.keys(o).sort(),
            key = keys.join('|'),
            value = keys.map(function (k) { return o[k]; }).join('|');

        hash[key] = hash[key] || {};
        hash[key][value] = (hash[key][value] || 0) + 1;
    });

    return array2.every(function (o) {
        var keys = Object.keys(o).sort(),
            key = keys.join('|'),
            value = keys.map(function (k) { return o[k]; }).join('|');

        return hash[key] && hash[key][value] && hash[key][value]--;
    });
}

console.log(pareArrays([{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }], [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }]));
console.log(pareArrays([{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }, { baz: 'baz' }], [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }]));
console.log(pareArrays([{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }, { foo: 'baz' }], [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }]));
console.log(pareArrays([{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }, { foo: 'baz' }], [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }, { foo: 42 }]));

You can try something like below

  • Reduce multiple objects in each array into one
  • Sort keys and build a 2D array or build a new object
  • Compare the two newly built data structures (2D arrays / objects)

This can be extrapolted to any number of arrays

const arr1 = [{ foo: 'foo', bar: 'bar' }, { baz: 'baz' }]; 
const arr2 = [{ baz: 'baz' }, { foo: 'foo', bar: 'bar' }];

// Method that sorts the object keys and builds a new object
// sortObj = (obj) =>
//   Object.keys(obj).sort().reduce((a, b) => {a[b] = obj[b]; return a}, {})
  
// Method that sorts keys and builds a 2D array
sortObj = (obj) =>
    Object.keys(obj).sort().map((key) => [key, obj[key]])

pareObj = (arr1, arr2) => {
  if(arr1.length !== arr2.length)
     return false;
 
  // 1st array reduce
  const reduceArr1 = arr1.reduce((a, b) => ({...a, ...b}), {});
  
  // 2nd array reduce
  const reduceArr2 = arr2.reduce((a, b) => ({...a, ...b}), {});
  
  // Comparing the sortedObjects
  return JSON.stringify(sortObj(reduceArr1)) === JSON.stringify(sortObj(reduceArr2))
}

console.log(pareObj(arr1, arr2))

发布评论

评论列表(0)

  1. 暂无评论