Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript中比较两个非有序对象数组的自定义实现_Javascript_Lodash - Fatal编程技术网

Javascript中比较两个非有序对象数组的自定义实现

Javascript中比较两个非有序对象数组的自定义实现,javascript,lodash,Javascript,Lodash,我想比较两个对象数组,如果它们的元素相同,但顺序不同,则应认为它们相等。e、 g.[{a:1},{b:2}]和[{b:2},{a:1}] 我使用的是lodash-v3的isEqual,它可以比较两个值,但它只在数组中的顺序相同时才提供true,因此我实现了一个递归比较元素的函数 function deepEqual(data1, data2) { data1 = _.cloneDeep(data1); data2 = _.cloneDeep(data2); function isDe

我想比较两个对象数组,如果它们的元素相同,但顺序不同,则应认为它们相等。e、 g.
[{a:1},{b:2}]和[{b:2},{a:1}]

我使用的是lodash-v3的
isEqual
,它可以比较两个值,但它只在数组中的顺序相同时才提供true,因此我实现了一个递归比较元素的函数

function deepEqual(data1, data2) {
  data1 = _.cloneDeep(data1);
  data2 = _.cloneDeep(data2);
  function isDeepEqual(val1, val2) {
    if (_.isArray(val1) && _.isArray(val2)) {
      if (val1.length === val2.length) {
        for (let id1 in val1) {
          let hasMatch = false;
          let matchOnIndex = -1;
          for (let id2 in val2) {
            if (isDeepEqual(val1[id1], val2[id2])) {
              hasMatch = true;
              matchOnIndex = id2;
              break;
            }
          }
          if (hasMatch) {
            val2.splice(matchOnIndex, 1);
          } else {
            return false;
          }
        }
        return true;
      } else {
        return false;
      }
    }

    if (_.isPlainObject(val1) && _.isPlainObject(val2)) {
      if (Object.keys(val1).length === Object.keys(val2).length) {
        for (let temp1 in val1) {
          if (!isDeepEqual(val1[temp1], val2[temp1])) {
            return false;
          }
        }
        return true;
      } else {
        return false;
      }
    }
    return _.isEqual(val1, val2);
  }

  return isDeepEqual(data1, data2);
}
上面的函数是有效的,但如何从性能方面改进它呢? 如果有任何简单的lodash3实现也适合我

链接到上述函数的

编辑

两个对象数组可以嵌套, e、 g

阵列也不能具有唯一值(因为用户正在创建此阵列)

这可能与@Koushik和@tokland建议的
.isEqualWith
有关。不幸的是,它可从lodashv4,所以我不能使用它。 本文还提到了类似的解决方案


真的很抱歉没有明确说明示例。小提琴有各种各样的箱子。

我想这就是你想要的

var first = [{ a: 1 }, { b: 2 }];
        var second = [{ b: 2 }, { a: 1 }];
function comparer(otherArray){
  return function(current){
    return otherArray.filter(function(other){
      return other.a == current.a && other.b == current.b
    }).length == 0;
  }
}
var onlyInA = first.filter(comparer(second));
var onlyInB = second.filter(comparer(first));
result = (onlyInA.concat(onlyInB)).length===0;
console.log(result);
功能应该是起点。现在,有很多方法可以实现它。通过为数组中的项定义顺序,可以使其非常有效。使用
id
作为键的示例:

function isEqualConsideringArraysAsSets(obj1, obj2, key) {
  const customizer = (objValue, othValue) => {
    if (_(objValue).isArray() && _(othValue).isArray()) {
      return _.size(objValue) === _.size(othValue) &&
        _.zip(_.sortBy(objValue, key), _.sortBy(othValue, key))
          .every(([val1, val2]) => isEqualConsideringArraysAsSets(val1, val2));
    }
  };

  return _.isEqualWith(obj1, obj2, customizer);
}

console.log(isEqualConsideringArraysAsSets([{id: 1}, {id: 2}], [{id: 2}, {id: 1}], "id"))

只需检查一个
数组
的每个
对象
在另一个
数组
中出现,并且具有相同的
长度
(两个数组)如何

让a1=[{a:1},{b:2}],
a2=[{b:2},{a:1}];
设isEqualArray=(arr1,arr2)=>(
arr1==arr2 | |
arr1.length==arr2.length&&
!arr1.some(a=>!arr2.find(b=>u0.isEqual(a,b)))
)
控制台日志(等质量射线(a1,a2))

使用计数排序来比较数组的内容。这将给你O(n)而不是你目前拥有的O(n^2)。@miradham,你能给我一个简单的例子或算法来比较两个对象数组的计数排序吗?我认为它只适用于数字数组。通过计数排序,我的意思是,您可以散列值,并只检查一次其数量和存储值。但我说它可以提高性能是错误的。在您的示例中,具有相同键的对象可以有多个值,因此您必须检查每个值,这将为您提供O(n^2)。您缺少
var first = [{ a: 1 }, { b: 2 }];
        var second = [{ b: 2 }, { a: 1 }];
function comparer(otherArray){
  return function(current){
    return otherArray.filter(function(other){
      return other.a == current.a && other.b == current.b
    }).length == 0;
  }
}
var onlyInA = first.filter(comparer(second));
var onlyInB = second.filter(comparer(first));
result = (onlyInA.concat(onlyInB)).length===0;
console.log(result);
function isEqualConsideringArraysAsSets(obj1, obj2, key) {
  const customizer = (objValue, othValue) => {
    if (_(objValue).isArray() && _(othValue).isArray()) {
      return _.size(objValue) === _.size(othValue) &&
        _.zip(_.sortBy(objValue, key), _.sortBy(othValue, key))
          .every(([val1, val2]) => isEqualConsideringArraysAsSets(val1, val2));
    }
  };

  return _.isEqualWith(obj1, obj2, customizer);
}

console.log(isEqualConsideringArraysAsSets([{id: 1}, {id: 2}], [{id: 2}, {id: 1}], "id"))
let isEqualArray = (arr1, arr2) => (
        arr1 === arr2 ||    
        arr1.length === arr2.length && 
        !arr1.some(a=> !arr2.find(b=>_.isEqual(a,b)))
)