Tôi thực hiện một cách tiếp cận đa năng hơn một chút, mặc dù tương tự trong các ý tưởng với các cách tiếp cận của cả @cerbrus và @kasper moerch. Tôi tạo một hàm chấp nhận vị từ để xác định xem hai đối tượng có bằng nhau không [ở đây chúng tôi bỏ qua thuộc tính $$hashKey
, nhưng nó có thể là bất cứ điều gì] và trả về một hàm tính toán sự khác biệt đối xứng của hai danh sách dựa trên vị từ đó:@Cerbrus and @Kasper Moerch. I create a function that accepts a predicate to determine if two objects are equal [here we ignore the $$hashKey
property, but it could be anything] and
return a function which calculates the symmetric difference of two lists based on that predicate:
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"}
Nó có một lợi thế nhỏ so với cách tiếp cận của Cerebrus [cũng như cách tiếp cận của Kasper Moerch] ở chỗ nó thoát ra sớm; Nếu nó tìm thấy một trận đấu, nó không bận tâm đến việc kiểm tra phần còn lại của danh sách. Nếu tôi có chức năng curry
tiện dụng, tôi sẽ làm điều này một chút khác nhau, nhưng điều này hoạt động tốt.
Giải trình
Một bình luận yêu cầu một lời giải thích chi tiết hơn cho người mới bắt đầu. Đây là một nỗ lực.
Chúng tôi chuyển chức năng sau đây cho
function[x, y] {
return x.value === y.value && x.display === y.display;
}
0:function[x, y] {
return x.value === y.value && x.display === y.display;
}
Hàm này là cách chúng tôi quyết định rằng hai đối tượng bằng nhau. Giống như tất cả các chức năng trả về
function[x, y] {
return x.value === y.value && x.display === y.display;
}
1 hoặc function[x, y] {
return x.value === y.value && x.display === y.display;
}
2, nó có thể được gọi là "hàm vị ngữ", nhưng đó chỉ là thuật ngữ. Điểm chính là function[x, y] {
return x.value === y.value && x.display === y.display;
}
0 được cấu hình với hàm chấp nhận hai đối tượng và trả về function[x, y] {
return x.value === y.value && x.display === y.display;
}
1 nếu chúng ta coi chúng như nhau, function[x, y] {
return x.value === y.value && x.display === y.display;
}
2 nếu chúng ta không.Sử dụng điều đó,
function[x, y] {
return x.value === y.value && x.display === y.display;
}
0 [đọc "Tạo chức năng khác biệt đối xứng"] trả về chúng tôi một chức năng mới: return function[a, b] {
return complement[pred, a, b].concat[complement[pred, b, a]];
};
Đây là chức năng chúng tôi thực sự sẽ sử dụng. Chúng tôi vượt qua nó hai danh sách và nó tìm thấy các yếu tố trong phần đầu tiên không phải trong phần thứ hai, sau đó các yếu tố trong phần thứ hai không trong phần thứ nhất và kết hợp hai danh sách này.
Tuy nhiên, nhìn lại nó, tôi chắc chắn có thể lấy một gợi ý từ mã của bạn và đơn giản hóa chức năng chính khá nhiều bằng cách sử dụng
function[x, y] {
return x.value === y.value && x.display === y.display;
}
7: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]];
};
};
}[]];
function[x, y] {
return x.value === y.value && x.display === y.display;
}
8 sử dụng vị ngữ và trả về các yếu tố của danh sách đầu tiên không phải trong lần thứ hai. Điều này đơn giản hơn so với đường chuyền đầu tiên của tôi với chức năng function[x, y] {
return x.value === y.value && x.display === y.display;
}
9 riêng biệt.Cuối cùng, chức năng chính được bọc trong biểu thức chức năng được gọi ngay lập tức [IIFE] để giữ hàm
function[x, y] {
return x.value === y.value && x.display === y.display;
}
8 bên trong ra khỏi phạm vi toàn cầu.IIFE] to keep the internal function[x, y] {
return x.value === y.value && x.display === y.display;
}
8 function out of the global scope.Cập nhật, một vài năm sau
Bây giờ ES2015 đã trở nên phổ biến khá tốt, tôi sẽ đề xuất cùng một kỹ thuật, với nhiều nồi hơi ít hơn:
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"}
Nhận sự khác biệt giữa hai mảng đối tượng #
Để có được sự khác biệt giữa hai mảng của các đối tượng:
- Sử dụng phương thức
1 để lặp qua mảng đầu tiên.return function[a, b] { return complement[pred, a, b].concat[complement[pred, b, a]]; };
- Kiểm tra xem mỗi đối tượng không được chứa trong mảng thứ hai.
- Lặp lại các bước
2 vàreturn function[a, b] { return complement[pred, a, b].concat[complement[pred, b, a]]; };
3 cho mảng thứ hai.return function[a, b] { return complement[pred, a, b].concat[complement[pred, b, a]]; };
- Concatenate kết quả để có được sự khác biệt hoàn toàn.
Copied!
const arr1 = [ {id: 1, name: 'Tom'}, {id: 2, name: 'John'}, ]; const arr2 = [{id: 1, name: 'Tom'}]; function getDifference[array1, array2] { return array1.filter[object1 => { return !array2.some[object2 => { return object1.id === object2.id; }]; }]; } // 👇️ [{id: 2, name: 'John'}] console.log[getDifference[arr1, arr2]];
Hàm chúng tôi đã chuyển đến phương thức mảng. Phương thức được gọi với từng phần tử [đối tượng] trong mảng.
Trên mỗi lần lặp, chúng tôi sử dụng phương thức mảng.some trên mảng thứ hai.
Hàm chúng tôi chuyển đến phương thức
return function[a, b] {
return complement[pred, a, b].concat[complement[pred, b, a]];
};
4 cũng được gọi với từng phần tử [đối tượng] trong mảng.Phương pháp
7 kiểm tra xem ít nhất một phần tử trong mảng có truyền điều kiện hay không. Chúng tôi kiểm tra xem ít nhất đối tượng function[x, y] {
return x.value === y.value && x.display === y.display;
}
2 từ mảng thứ nhất có cùng thuộc tính return function[a, b] {
return complement[pred, a, b].concat[complement[pred, b, a]];
};
7 dưới dạng đối tượng từ mảng thứ hai. return function[a, b] {
return complement[pred, a, b].concat[complement[pred, b, a]];
};
Chúng tôi đã sử dụng toán tử logic không [!] Để phủ nhận kết quả từ phương thức
function[x, y] {
return x.value === y.value && x.display === y.display;
}
7, bởi vì chúng tôi chỉ quan tâm đến các đối tượng không có cùng thuộc tính return function[a, b] {
return complement[pred, a, b].concat[complement[pred, b, a]];
};
7 giữa các mảng.Nếu điều kiện được đáp ứng, phương thức
function[x, y] {
return x.value === y.value && x.display === y.display;
}
7 trả về function[x, y] {
return x.value === y.value && x.display === y.display;
}
1 và đối tượng được đưa vào mảng, phương thức 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]];
};
};
}[]];
2 trả về.Tuy nhiên, chúng tôi chỉ gọi phương thức
2 trên một trong các mảng. Vậy điều gì xảy ra nếu mảng đầu tiên chứa ít phần tử hơn thứ hai?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]];
};
};
}[]];
Copied!
const arr1 = [{id: 1, name: 'Tom'}]; // 📌 now second array has 2 elements const arr2 = [ {id: 1, name: 'Tom'}, {id: 2, name: 'John'}, ]; function getDifference[array1, array2] { return array1.filter[object1 => { return !array2.some[object2 => { return object1.id === object2.id; }]; }]; } // 👇️ [] console.log[getDifference[arr1, arr2]];
Điều duy nhất mà chúng tôi đã thay đổi là chúng tôi đã chuyển các giá trị giữa các biến
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]];
};
};
}[]];
4 và 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]];
};
};
}[]];
5.Bây giờ chúng tôi gọi phương thức
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]];
};
};
}[]];
2 trên mảng đầu tiên, tuy nhiên đối tượng duy nhất mà nó chứa cũng chứa trong mảng thứ hai, do đó phương thức 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]];
};
};
}[]];
7 trả về một mảng trống.Chúng tôi hy vọng giá trị trả lại sẽ là
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]];
};
};
}[]];
8.Để giải quyết vấn đề này, chúng ta cần gọi phương pháp
7 hai lần và kết hợp kết quả.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]];
};
};
}[]];
Copied!
const arr1 = [{id: 1, name: 'Tom'}]; const arr2 = [ {id: 1, name: 'Tom'}, {id: 2, name: 'John'}, ]; function getDifference[array1, array2] { return array1.filter[object1 => { return !array2.some[object2 => { return object1.id === object2.id; }]; }]; } const difference = [ ...getDifference[arr1, arr2], ...getDifference[arr2, arr1] ]; // 👇️ [{id: 2, name: 'John'}] console.log[difference];
Đây là những gì chúng tôi đã làm để có được điều này hoạt động:
- Gọi phương thức
2 trên mảng đầu tiên và chỉ trả về các đối tượng không có trong mảng thứ hai.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]]; }; }; }[]];
- Gọi phương thức
2 trên mảng thứ hai và chỉ trả về các đối tượng không có trong mảng thứ nhất.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]]; }; }; }[]];
- Chúng tôi đã kết hợp các kết quả từ hai mảng thành một mảng thứ ba, sử dụng cú pháp của toán tử [...].
Một cách dễ dàng để suy nghĩ về toán tử lây lan [...] là chúng tôi đang giải nén các giá trị của một mảng vào một mảng khác.
Bây giờ ví dụ của chúng tôi đã hoàn tất và trả về sự khác biệt giữa hai mảng của các đối tượng.
Đọc thêm #
- Nhận giao điểm của hai mảng trong JavaScript
- Nhận sự khác biệt giữa hai mảng trong JavaScript