JS - 在具有未知数量属性的2个对象数组之间找到差异

时间:2017-11-17 10:00:08

标签: javascript arrays sorting underscore.js difference

我有2个包含相同属性的对象数组,但根据情况它们可以有1-50个属性。我需要区分这两个

数组1:

[
  {
    "prop1": 1,
    "prop2": 2
  },
  {
    "prop1": 4,
    "prop2": 4
  },
  {
    "prop1": 3,
    "prop2": 7
  },
  {
    "prop1": 1,
    "prop2": 3
  }
]

数组2:

[
  {
    "prop1": 1,
    "prop2": 2
  },
  {
    "prop1": 4,
    "prop2": 4
  }
]

我尝试使用下划线的差异功能,但在这种情况下效果不佳。我正在考虑获取对象键,对其进行排序并对对象进行哈希处理。我可以比较但我需要将其恢复为原始格式。而且由于这些阵列最多可以有5000个物体,因此它看起来很昂贵。

是否有一个有效的解决方案?

编辑:我已经看到问题Difference between two array of objects in JavaScript,但该示例具有静态数量的属性,他在该属性上过滤数组。事实并非如此;我不知道名字,也不知道数量。

1 个答案:

答案 0 :(得分:1)

您可以先获取一些哈希表,先获取密钥然后再获取值,然后检查另一个数组的哈希并过滤结果。

此提案返回两个数组的对称差异。

function getDifference(a, b) {
    function getKeyValue(object) {
        var keys = Object.keys(object).sort();
        return {
            key: keys.join('|'),
            value: keys.map(function (k) { return object[k]; }).join('|')
        };
    }

    function setHash(hash, kv) {
        hash[kv.key] = hash[kv.key] || {};
        hash[kv.key][kv.value] = true;
    }

    function isHash(hash, kv) {
        return hash[kv.key] && hash[kv.key][kv.value];
    }

    var hashA = Object.create(null),
        hashB = Object.create(null),
        result;

    b.forEach(function (o) {
        var kv = getKeyValue(o);
        setHash(hashB, kv);
    });

    return Array.prototype.concat(
        [],
        array1.filter(function (o) {
            var kv = getKeyValue(o);
            setHash(hashA, kv);
            return !isHash(hashB, kv);
        }),
        array2.filter(function (o) {
            var kv = getKeyValue(o);
            return !isHash(hashA, kv);
        })
    );
}

var array1 = [{ prop1: 1, prop2: 2 }, { prop1: 4, prop2: 4 }, { prop1: 3, prop2: 7 }, { prop1: 1, prop2: 3 }, { prop2: 3 }],
    array2 = [{ prop1: 1, prop2: 2 }, { prop1: 4, prop2: 4 }, { prop1: 4 }];

console.log(getDifference(array1, array2));
.as-console-wrapper { max-height: 100% !important; top: 0; }