简体   繁体   English

递归比较javascript中的一组对象

[英]Compare an array of objects in javascript recursively

I make an ajax call that returns an array of objects.我进行了一个返回对象数组的ajax调用。 The array can contain 1 object or 20, it is not known before making the call.该数组可以包含 1 个对象或 20 个,在调用之前是未知的。

The objects will have the same properties but different values.这些对象将具有相同的属性但不同的值。 I can compare two objects like this:我可以像这样比较两个对象:

function compareObjects(x, y) {
   var objectsAreSame = true;
   for(var propertyName in x) {
      if(x[propertyName] !== y[propertyName]) {
         objectsAreSame = false;
         break;
      }
   }
   return objectsAreSame;
}

How can I extend this to compare several objects or is there a better way to compare ?如何扩展它以比较多个对象,或者有更好的比较方法?

Edit#1 Similar question here: Object comparison in JavaScript编辑#1 类似问题: Object compare in JavaScript

However, I am not trying to compare two objects, I am trying to find the shortest possible way to compare an unknown array of objects.但是,我不是要比较两个对象,而是要找到比较未知对象数组的最短方法。 I apologize for any confusion.对于任何混淆,我深表歉意。

Edit #2 I am not asking how to compare two objects.编辑 #2 我不是在问如何比较两个对象。 I am asking how to take an array of unknown quantities and compare every object inside and check if every object is the same.我在问如何获取一组未知量并比较里面的每个对象并检查每个对象是否相同。

Like arrayofObjects[obj1, obj2...objn] simplest way to say obj1, through objn are exactly the same.像arrayofObjects[obj1, obj2...objn] 最简单的说法就是obj1,通过objn 都是一模一样的。

Keeping your fonction as is (it's very simplistic but let's assume it works in your use case):保持您的功能不变(这很简单,但让我们假设它适用于您的用例):

const sameArray = (newArray.length === oldArray.length) && newArray.every((item, index) =>
  compareObjects(item, oldArray[index])
)

Stringify 'em!把它们串起来!

var same = JSON.stringify(x) === JSON.stringify(y);

Edit: OP's slight edit can change this answer a bit.编辑:OP 的轻微编辑可以稍微改变这个答案。 I thought he wanted to know if obj1 === obj2 (if they're exactly the same).我以为他想知道 obj1 === obj2 (如果它们完全相同)。 This will do that well but not if properties can be in different orders and still be considered "same" for his use case.这会做得很好,但如果属性可以处于不同的顺序并且仍然被认为是他的用例“相同”,则不会。

I would do this with a generic method Object.prototype.compare() as follows我会用一个通用方法Object.prototype.compare()来做到这一点,如下所示

Object.prototype.compare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};

You can use Array.prototype.every() and compare all objects in the array using the first object as reference for the comparison.您可以使用Array.prototype.every()并使用第一个对象作为比较参考来比较数组中的所有对象。

function compareArray(array) {
  return array.every(compareObjects.bind(null, array[0]));
}

 function compareObjects(x, y) { var objectsAreSame = true; for(var propertyName in x) { if(x[propertyName] !== y[propertyName]) { objectsAreSame = false; break; } } return objectsAreSame; } function compareArray(array) { return array.every(compareObjects.bind(null, array[0])); } var array1 = [ { a: 1 }, { a: 1 }, { a: 1 }, { a: 1 } ]; var array2 = [ { a: 1 }, { b: 1 }, { c: 1 }, { d: 1 } ]; console.log(compareArray(array1)); console.log(compareArray(array2));

In case if you need to compare array of objects and objects can contain arrays and each array can contain something different from object, you can use this:如果您需要比较对象数组并且对象可以包含数组并且每个数组可以包含与对象不同的内容,则可以使用以下命令:

const isEqual = (a, b) => {
    if (typeof a === "object" && typeof b === "object") {
        if (Array.isArray(a) && Array.isArray(b)) {
            return a.every((item, index) => isEqual(item, b[index]));
        }
        return Object.entries(a).toString() === Object.entries(b).toString();
    }

    return a === b;
};

For array this function will called recursively对于数组,此函数将递归调用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM