[javascript] lodash를 사용하여 두 개체를 심도있게 비교하는 방법은 무엇입니까?
다른 중첩 된 객체가 2 개 있으며 중첩 된 속성 중 하나에 차이가 있는지 알아야합니다.
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
더 중첩 된 속성으로 인해 개체가 훨씬 복잡해질 수 있습니다. 그러나 이것은 좋은 예입니다. 재귀 함수 또는 lodash와 함께 사용할 수있는 옵션이 있습니다 …
답변
쉽고 우아한 솔루션을 사용 _.isEqual
하면 깊게 비교할 수 있습니다.
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
_.isEqual(a, b); // returns false if different
그러나이 솔루션은 어떤 속성이 다른지 보여주지 않습니다.
답변
어떤 속성이 다른지 알아야하는 경우 reduce ()를 사용하십시오 .
_.reduce(a, function(result, value, key) {
return _.isEqual(value, b[key]) ?
result : result.concat(key);
}, []);
// → [ "prop2" ]
답변
이 스레드를 다루는 모든 사람을 위해 더 완벽한 솔루션이 있습니다. 그것은 비교합니다 두 개체를 당신에게 중 모든 속성의 키주는 유일한 오브젝트 1 년을 , 단지 object2에서 , 또는이다 오브젝트 1 및 object2 모두 있지만 다른 값을 가질 :
/*
* Compare two objects by reducing an array of keys in obj1, having the
* keys in obj2 as the intial value of the result. Key points:
*
* - All keys of obj2 are initially in the result.
*
* - If the loop finds a key (from obj1, remember) not in obj2, it adds
* it to the result.
*
* - If the loop finds a key that are both in obj1 and obj2, it compares
* the value. If it's the same value, the key is removed from the result.
*/
function getObjectDiff(obj1, obj2) {
const diff = Object.keys(obj1).reduce((result, key) => {
if (!obj2.hasOwnProperty(key)) {
result.push(key);
} else if (_.isEqual(obj1[key], obj2[key])) {
const resultKeyIndex = result.indexOf(key);
result.splice(resultKeyIndex, 1);
}
return result;
}, Object.keys(obj2));
return diff;
}
다음은 예제 출력입니다.
// Test
let obj1 = {
a: 1,
b: 2,
c: { foo: 1, bar: 2},
d: { baz: 1, bat: 2 }
}
let obj2 = {
b: 2,
c: { foo: 1, bar: 'monkey'},
d: { baz: 1, bat: 2 }
e: 1
}
getObjectDiff(obj1, obj2)
// ["c", "e", "a"]
중첩 된 객체를 신경 쓰지 않고 lodash를 건너 뛰려면 _.isEqual
일반적인 값 비교를 대신 할 수 있습니다 (예 🙂 obj1[key] === obj2[key]
.
답변
Adam Boduch의 답변을 바탕으로 두 기능을 가장 깊은 의미에서 비교 하는이 기능을 작성했습니다. 다른 값을 가진 경로와 하나 또는 다른 객체에서 누락 된 경로를 반환 .
이 코드는 효율성을 염두에두고 작성되지 않았으며 그 점에서 개선 된 부분이 가장 환영 받지만 기본 형식은 다음과 같습니다.
var compare = function (a, b) {
var result = {
different: [],
missing_from_first: [],
missing_from_second: []
};
_.reduce(a, function (result, value, key) {
if (b.hasOwnProperty(key)) {
if (_.isEqual(value, b[key])) {
return result;
} else {
if (typeof (a[key]) != typeof ({}) || typeof (b[key]) != typeof ({})) {
//dead end.
result.different.push(key);
return result;
} else {
var deeper = compare(a[key], b[key]);
result.different = result.different.concat(_.map(deeper.different, (sub_path) => {
return key + "." + sub_path;
}));
result.missing_from_second = result.missing_from_second.concat(_.map(deeper.missing_from_second, (sub_path) => {
return key + "." + sub_path;
}));
result.missing_from_first = result.missing_from_first.concat(_.map(deeper.missing_from_first, (sub_path) => {
return key + "." + sub_path;
}));
return result;
}
}
} else {
result.missing_from_second.push(key);
return result;
}
}, result);
_.reduce(b, function (result, value, key) {
if (a.hasOwnProperty(key)) {
return result;
} else {
result.missing_from_first.push(key);
return result;
}
}, result);
return result;
}
이 스 니펫을 사용하여 코드를 시도 할 수 있습니다 (전체 페이지 모드에서 실행하는 것이 좋습니다).
답변
간결한 솔루션은 다음과 같습니다.
_.differenceWith(a, b, _.isEqual);
답변
객체가 다른 객체와 어떻게 다른지 재귀 적으로 보여주기 위해 _.isduce 와 _.isEqual 및 _.isPlainObject를 사용할 수 있습니다 . 이 경우 a와 b의 차이점 또는 b와 a의 차이점을 비교할 수 있습니다.
var a = {prop1: {prop1_1: 'text 1', prop1_2: 'text 2', prop1_3: [1, 2, 3]}, prop2: 2, prop3: 3};
var b = {prop1: {prop1_1: 'text 1', prop1_3: [1, 2]}, prop2: 2, prop3: 4};
var diff = function(obj1, obj2) {
return _.reduce(obj1, function(result, value, key) {
if (_.isPlainObject(value)) {
result[key] = diff(value, obj2[key]);
} else if (!_.isEqual(value, obj2[key])) {
result[key] = value;
}
return result;
}, {});
};
var res1 = diff(a, b);
var res2 = diff(b, a);
console.log(res1);
console.log(res2);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>
답변
간단한 사용 _.isEqual
방법, 그것은 모든 비교를 위해 작동합니다 …
- 참고 : 이 방법은 배열, 배열 버퍼, 부울, * 날짜 오브젝트, 오류 오브젝트, 맵, 숫자,
Object
오브젝트, 정규 표현식, * 세트, 문자열, 기호 및 유형 배열 비교를 지원합니다.Object
객체는 상속 가능하지 않고 열거 가능한 속성으로 * 비교됩니다. 함수 및 DOM * 노드는 지원 되지 않습니다 .
아래에 있다면 :
const firstName = {name: "Alireza"};
const otherName = {name: "Alireza"};
당신이 할 경우 : _.isEqual(firstName, otherName);
,
돌아올 것이다 사실 합니다
그리고 만약 const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
당신이 할 경우 : _.isEqual(firstName, fullName);
,
거짓 을 반환합니다