簡體   English   中英

在Javascript中比較兩個對象的無序數組的自定義實現

[英]Custom implementation of comparing two non ordered array of object in Javascript

我想比較兩個對象數組,如果它們的元素相同但順序不同,則應將它們視為相等。 例如[{a:1}, {b:2}] and [{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的任何簡單實現對我也適用。

鏈接到上述函數的小提琴

編輯

可以嵌套兩個對象數組,例如

[{
  a:1,
  b:[{
    c: [1, 2]
  },
  {
    d: [3, 4]
  }]
},{
  e:1,
  f:[{
    g: [5, 6]
  },
  {
    h: [7, 8]
  }]
}]

[{
  e:1,
  f:[{
    h: [8, 7]
  },{
    g: [6, 5]
  }]
},{
  a:1,
  b:[{
    d: [4, 3]
  },{
    c: [2, 1]
  }]
}]

數組也不能具有唯一值(因為用戶正在創建此數組)。

可以使用_.isEqualWith如@Koushik和@tokland建議的那樣。 不幸的是,可以從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);

函數_.isEqualWith應該是起點。 現在,有很多方法可以實現它。 您可以通過為數組中的項目定義順序來使其非常有效。 使用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"))

簡單地檢查一個array每個Object存在於另一個array並且具有相同的length (兩個數組)如何呢?

let isEqualArray = (arr1, arr2) => (
        arr1 === arr2 ||    
        arr1.length === arr2.length && 
        !arr1.some(a=> !arr2.find(b=>_.isEqual(a,b)))
)

 let a1 = [{a:1}, {b:2}], a2 = [{b:2}, {a:1}]; let isEqualArray = (arr1, arr2) => ( arr1 === arr2 || arr1.length === arr2.length && !arr1.some(a=> !arr2.find(b=>_.isEqual(a,b))) ) console.log(isEqualArray(a1,a2)); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script> 

_.isEqual_.isEqualWith與定制器的用法取決於您要如何比較兩個對象!

注意:當陣列中有重復項時,這將不會100%起作用,但是它將至少確認一個陣列中的所有項都存在於另一個陣列中。 您可以進行反向檢查,也可以應用唯一方法對重復的數組執行此比較。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM