요청에 따라 재귀 객체 비교 기능이 있습니다. 그리고 조금 더. 이러한 기능을 주로 사용하는 것이 객체 검사라고 가정하면 할 말이 있습니다. 약간의 차이점이 무의미한 경우 완전한 심층 비교는 나쁜 생각입니다. 예를 들어, TDD 어설 션에서 맹목적으로 비교하면 테스트가 불필요 해지기 쉽습니다. 이런 이유로 훨씬 더 유용한 부분 diff 를 소개하고 싶습니다 . 이 스레드에 대한 이전의 기여와 재귀적인 유사체입니다. 에없는 키는 무시합니다 .
var bdiff = (a, b) =>
_.reduce(a, (res, val, key) =>
res.concat((_.isPlainObject(val) || _.isArray(val)) && b
? bdiff(val, b[key]).map(x => key + '.' + x)
: (!b || val != b[key] ? [key] : [])),
[]);
BDiff를 사용하면 자동 검사에 원하는 다른 속성을 허용하면서도 예상 값을 확인할 수 있습니다 . 이를 통해 모든 종류의 고급 어설 션을 작성할 수 있습니다. 예를 들면 다음과 같습니다.
var diff = bdiff(expected, actual);
// all expected properties match
console.assert(diff.length == 0, "Objects differ", diff, expected, actual);
// controlled inequality
console.assert(diff.length < 3, "Too many differences", diff, expected, actual);
완전한 솔루션으로 돌아갑니다. bdiff를 사용하여 전통적인 diff를 만드는 것은 쉽지 않습니다.
function diff(a, b) {
var u = bdiff(a, b), v = bdiff(b, a);
return u.filter(x=>!v.includes(x)).map(x=>' < ' + x)
.concat(u.filter(x=>v.includes(x)).map(x=>' | ' + x))
.concat(v.filter(x=>!u.includes(x)).map(x=>' > ' + x));
};
두 개의 복잡한 객체에서 위의 기능을 실행하면 다음과 비슷한 결과가 출력됩니다.
[
" < components.0.components.1.components.1.isNew",
" < components.0.cryptoKey",
" | components.0.components.2.components.2.components.2.FFT.min",
" | components.0.components.2.components.2.components.2.FFT.max",
" > components.0.components.1.components.1.merkleTree",
" > components.0.components.2.components.2.components.2.merkleTree",
" > components.0.components.3.FFTResult"
]
마지막으로, 값이 어떻게 다른지 엿볼 수 있도록 diff 출력 을 직접 eval () 할 수 있습니다 . 이를 위해서는 구문 적으로 올바른 경로를 출력 하는 못생긴 bdiff 버전이 필요 합니다.
// provides syntactically correct output
var bdiff = (a, b) =>
_.reduce(a, (res, val, key) =>
res.concat((_.isPlainObject(val) || _.isArray(val)) && b
? bdiff(val, b[key]).map(x =>
key + (key.trim ? '':']') + (x.search(/^\d/)? '.':'[') + x)
: (!b || val != b[key] ? [key + (key.trim ? '':']')] : [])),
[]);
// now we can eval output of the diff fuction that we left unchanged
diff(a, b).filter(x=>x[1] == '|').map(x=>[x].concat([a, b].map(y=>((z) =>eval('z.' + x.substr(3))).call(this, y)))));
다음과 비슷한 결과가 출력됩니다.
[" | components[0].components[2].components[2].components[2].FFT.min", 0, 3]
[" | components[0].components[2].components[2].components[2].FFT.max", 100, 50]
MIT 라이센스;)