isEqual против isMatch - isMatch игнорирует порядок вложенных элементов массива? - PullRequest
0 голосов
/ 23 января 2019

Я использую lodash для сравнения ниже двух объектов:

obj1 = {
    "_id": "57767",
    "Re": {
        "PropertyTypes": [
            {
                "AllocationID": 13870,
                "Percentage": null,
                "Type": "Hotels",
                "Value": null
            },
            {
                "AllocationID": 13867,
                "Percentage": null,
                "Type": "Industrial",
                "Value": null
            }
        ]
    }
}

obj2 = {
    "_id": "57767",
    "Re": {
        "PropertyTypes": [
            {
                "AllocationID": 13867,
                "Percentage": null,
                "Type": "Industrial",
                "Value": null
            },
            {
                "AllocationID": 13870,
                "Percentage": null,
                "Type": "Hotels",
                "Value": null
            }
        ]
    }
}

Я вижу, что с isEqual(obj1, obj2) сравнение не удается, а с isMatch(obj1, obj2) работает нормально.

Я хотел бы знать, работают ли оба isEqual и isMatch одинаково, за исключением того факта, что порядок элементов массива PropertyTypes игнорируется isMatch в этом случае.Я не нашел эту информацию в документации isMatch .

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Они на самом деле не работают одинаково, _.isMatch выполняет только глубокое сравнение частичное , а _.isEqual выполняет полное полное *1004* сравнение.

Таким образом, для примера двух простых объектов, мы получаем результаты ниже, isMatch возвращает true, так как они перекрываются.

И в вашем случае свойства "Re" obj1 и obj2 вообще не должны совпадать, чтобы _.isMatch вернул true.

let obj1 = {
    "_id": "57767",
    "Re": {
        "PropertyTypes": [
            {
                "AllocationID": 13870,
                "Percentage": null,
                "Type": "Hotels",
                "Value": null
            },
            {
                "AllocationID": 13867,
                "Percentage": null,
                "Type": "Industrial",
                "Value": null
            }
        ]
    }
}

// Remove Re property of obj2 to demonstrate.
let obj2 = {
    "_id": "57767",
    "Re": { 
    }
}

console.log("_.isEqual(obj1, obj2)", _.isEqual(obj1, obj2));
console.log("_.isMatch(obj1, obj2)", _.isMatch(obj1, obj2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
0 голосов
/ 23 января 2019

Не уверен, что вы подразумеваете под "работать точно так же", но вот мое понимание:

  • _.isMatch и _.isEqual имеют одинаковую внутреннюю логику, _isMatch звонит сказалбазовые логики с явными частичными и неупорядоченными флагами (так что, я думаю, мы можем сказать, что они работают вполне так же)
  • Я бы сказалчто обычно _isMatch должен использоваться для утверждения входного объекта - например, конфигурации - по крайней мере , хотя, может быть, и не совсем предварительно хорошо сформирован, тогда как _.isEqual обрабатывает самое чистое, самое строгое сравнение
  • из-за этого поведения, похожего на валидацию, существует также концепция частичного флага, который может быть ловушкой, учитывая данные, которые вы показываете, например:
obj1 = {
  a: 123,
  b: 456,
  c: 789
};
obj2 = {
  a: 123,
  b: 456
}
_.isMatch(obj1, obj2); // true, `c` wasn't "asserted"
_.isMatch(obj2, obj1); // false, missing value for `c`

Чтобы распространить это на примерближе к вашему делу, и так как это глубокое сравнение:

obj1 = {
  PropertyTypes: [{
    id: 13867
  }, {
    id: 13870
  }]
};
obj2 = {
  PropertyTypes: [{
    id: 13867
  }, {
    id: 13870
  }, {
    id: 11111
  }]
};
_.isMatch(obj1, obj2); // false, missing 11111 value
_.isMatch(obj2, obj1); // true, even though there's one more item in the array

Надеюсь, это поможет!

...