精慕HU
只使用本机JS,这样的东西会起作用的:a = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", display:"Jamsheer"}, { value:"644838b3-604d-4899-8b78-09e4799f586f", display:"Muhammed"}, { value:"b6ee537a-375c-45bd-b9d4-4dd84a75041d", display:"Ravi"}, { value:"e97339e1-939d-47ab-974c-1b68c9cfb536", display:"Ajmal"}, { value:"a63a6f77-c637-454e-abf2-dfb9b543af6c", display:"Ryan"}]b = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", display:"Jamsheer", $$hashKey:"008"}, { value:"644838b3-604d-4899-8b78-09e4799f586f", display:"Muhammed", $$hashKey:"009"}, { value:"b6ee537a-375c-45bd-b9d4-4dd84a75041d", display:"Ravi", $$hashKey:"00A"}, { value:"e97339e1-939d-47ab-974c-1b68c9cfb536", display:"Ajmal", $$hashKey:"00B"}]function comparer(otherArray){ return function(current){ return otherArray.filter(function(other){ return other.value == current.value && other.display == current.display }).length == 0; }}var onlyInA = a.filter(comparer(b));var onlyInB = b.filter(comparer(a));result = onlyInA.concat(onlyInB);console.log(result);
万千封印
我采取的是一种稍微通用的方法,尽管在思想上与两者的方法相似。@Cerbrus和@Kasper Moerch..我创建了一个接受谓词的函数来确定两个对象是否相等(这里我们忽略了$$hashKey属性,但它可以是任何内容)并返回一个函数,该函数根据该谓词计算两个列表的对称差异:a = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", display:"Jamsheer"}, { value:"644838b3-604d-4899-8b78-09e4799f586f", display:"Muhammed"}
, { value:"b6ee537a-375c-45bd-b9d4-4dd84a75041d", display:"Ravi"}, { value:"e97339e1-939d-47ab-974c-1b68c9cfb536", display:"Ajmal"},
{ value:"a63a6f77-c637-454e-abf2-dfb9b543af6c", display:"Ryan"}]b = [{ value:"4a55eff3-1e0d-4a81-9105-3ddd7521d642", display:"Jamsheer",
$$hashKey:"008"}, { value:"644838b3-604d-4899-8b78-09e4799f586f", display:"Muhammed", $$hashKey:"009"}, { value:"b6ee537a-375c-45bd-b9d4-
4dd84a75041d", display:"Ravi", $$hashKey:"00A"}, { value:"e97339e1-939d-47ab-974c-1b68c9cfb536", display:"Ajmal", $$hashKey:"00B"}]var
makeSymmDiffFunc = (function() {
var contains = function(pred, a, list) {
var idx = -1, len = list.length;
while (++idx < len) {if (pred(a, list[idx])) {return true;}}
return false;
};
var complement = function(pred, a, b) {
return a.filter(function(elem) {return !contains(pred, elem, b);});
};
return function(pred) {
return function(a, b) {
return complement(pred, a, b).concat(complement(pred, b, a));
};
};}());var myDiff = makeSymmDiffFunc(function(x, y) {
return x.value === y.value && x.display === y.display;});var result = myDiff(a, b);
//=> {value="a63a6f77-c637-454e-abf2-dfb9b543af6c", display="Ryan"}与Cerebrus的方法相比,它有一个小的优势(如同KasperMoerch的方法一样),因为它提前逃脱;如果它找到了匹配的,它就不会去检查列表的其余部分。如果我有一个curry函数HANDY,我会做一些不同的,但这是很好的工作。解释一条评论要求为初学者提供更详细的解释。这是一次尝试。我们将以下函数传递给makeSymmDiffFunc:function(x, y) {
return x.value === y.value && x.display === y.display;}这个函数是如何决定两个对象是相等的。就像所有返回的函数一样true或false,它可以被称为“谓词函数”,但这只是术语而已。重点是makeSymmDiffFunc配置为一个函数,该函数接受两个对象并返回true如果我们认为它们是平等的,false如果我们不这么做。用这个,makeSymmDiffFunc(阅读“制造对称差分函数”)返回一个新函数: return function(a, b) {
return complement(pred, a, b).concat(complement(pred, b, a));
};这是我们将实际使用的函数。我们传递给它两个列表,它在第一个列表中找到元素,然后在第二个列表中找到元素,然后在第一个列表中找到元素,然后将这两个列表组合在一起。不过,再看一遍,我肯定会从您的代码中得到提示,并通过以下方法对主函数进行相当大的简化some:var makeSymmDiffFunc = (function() {
var complement = function(pred, a, b) {
return a.filter(function(x) {
return !b.some(function(y) {return pred(x, y);});
});
};
return function(pred) {
return function(a, b) {
return complement(pred, a, b).concat(complement(pred, b, a));
};
};}());complement使用谓词并返回第一个列表中的元素,而不是第二个列表中的元素。这比我第一次单独通过contains功能。最后,主函数包装在一个立即调用的函数表达式中(生命)保持内部complement在全球范围之外发挥作用。更新,几年后既然ES 2015已经变得相当普及,我建议采用同样的技术,少得多的样板:const diffBy = (pred) => (a, b) => a.filter(x => !b.some(y => pred(x, y)))const makeSymmDiffFunc = (pred) => (a, b) =>
diffBy(pred)(a, b).concat(diffBy(pred)(b, a))const myDiff = makeSymmDiffFunc((x, y) => x.value === y.value && x.display
=== y.display)const result = myDiff(a, b)//=> {value="a63a6f77-c637-454e-abf2-dfb9b543af6c", display="Ryan"}