tôi thực sự có thể tưởng tượng tình huống mà tôi muốn sử dụng cách tiếp cận @ kontr0l hơn cái gì khác, nhưng bạn phải hiểu rằng phương pháp này là bậc hai, vì vậy về cơ bản mã này là một trừu tượng cho cách tiếp cận ngây thơ - lặp qua tất cả các giá trị trong hai mảng.
Có phương pháp tiếp cận tốt hơn so với bậc hai, tôi sẽ không sử dụng ở đây bất kỳ ký hiệu O lớn, nhưng đây là hai phương pháp chính, cả hai đều tốt hơn sau đó ngây thơ một:
- lặp thông qua một trong những mảng và kiểm tra cho sự tồn tại trong mảng thứ hai được sắp xếp bằng cách sử dụng tìm kiếm nhị phân.
- đặt giá trị vào tập hợp/băm/từ điển/bạn đặt tên cho nó.
Như đã được đề cập, cách tiếp cận đầu tiên có thể được áp dụng cho các đối tượng nếu bạn thực hiện lại phương pháp chuẩn difference
với sử dụng phương pháp tương tự linh hoạt hơn indexOf
.
Với cách tiếp cận thứ hai, chúng tôi có thể chạm vào tường với thực tế là, đến tháng 2 năm 2015, chỉ các trình duyệt hiện đại mới hỗ trợ Sets. Khi băm (tốt, các đối tượng) trong javascript, chúng có thể chỉ có các khóa kiểu chuỗi, vì vậy bất kỳ đối tượng nào được gọi là khóa đầu tiên được chuyển đổi thông qua phương thức toString
. Vì vậy, chúng tôi cần phải cung cấp một số => correspondece. Trên thực tế trong hầu hết các trường hợp, nó khá đơn giản, ví dụ, ví dụ cụ thể của bạn thư từ như vậy có thể chỉ là String(obj.id)
.
Có thư như vậy, chúng ta cũng có thể sử dụng lodas sau/cách tiếp cận undercore:
var idsA = _.pluck(a, 'id');
var idsB = _.pluck(b, 'id');
// actually here we can stop in some cases, because
// quite often we need to identify object, but not the object itself -
// for instance to send some ids through remote API.
var intersect = _.intersection(idsA, idsB);
//to be 100% sure you get the idea, here we assume that object having equal ids are treated as equal, so does not really matter which of arrays we'll iterate:
var dictA = _.object(idsA, a); // now we can find a by id faster then with _.find
var intersectObj = intersect.map(function(id) {return dictA[id})
Nhưng mua thừa nhận hạn chế hơi khắt khe hơn - mà chúng ta có thể xây dựng tương ứng giữa các đối tượng thiết lập của chúng tôi và các số tự nhiên chúng ta có thể xây dựng efficent thậm chí nhiều hơn thuật toán, tức là tất cả các id của chúng tôi là số nguyên không âm - chúng tôi có thể sử dụng thuật toán hiệu quả hơn.
Bí quyết là để thực hiện thiết lập bằng cách giới thiệu hai mảng helper theo cách này:
var naturalSet = function (arr) {
var sparse = [];
var dense = [];
var contains = function (i) {
var res = sparse[i] < dense.length && dense[sparse[i]] == i;
return res;
}
var add = function (v) {
if (!contains(v)) {
sparse[v] = dense.length;
dense.push(v);
}
}
arr.forEach(add);
return {
contains: contains,
toArray: function() {
return dense
},
_getDense: function() {
return dense
},
_getSparse: function() {
return sparse
}
}
}
Sau đó, chúng ta có thể giới thiệu thiết lập với bản đồ để naturalSet:
var set = function (arr, valueOf) {
var natSet = naturalSet(arr.map(valueOf));
return {
contains: function (item) {
return natSet.contains(valueOf(item))
},
toArray: function() {
var sparse = natSet._getSparse();
var res = natSet._getDense().map(function (i) {
return arr[sparse[i]];
});
return res;
}
}
}
và cuối cùng, chúng ta có thể giới thiệu giao lộ:
var intersection = function(arr1, arr2, valueOf) {
return set(arr2.filter(set(arr1, valueOf).contains), valueOf).toArray();
}
Vì vậy, dựa vào cấu trúc dữ liệu bạn đang làm việc có thể p bạn đôi khi.
tương tự (không trùng lặp) để http://stackoverflow.com/questions/8672383/how-to-use-underscores-intersection-on-objects – drzaus
và nếu bạn đến đây tìm kiếm sự khác biệt giữa hai vật (tức là delta của chúng, không phải giữa các mảng của các đối tượng), không có gì được tích hợp sẵn trong Underscore nhưng bạn có thể thử http://stackoverflow.com/a/25651677/1037948 – drzaus
Lưu ý rằng _difference (a, b) sẽ trả về [1, 3,4]. Phương thức _.difference sẽ trả về các phần tử của mảng đầu tiên không có trong __other arrays__ – Aegis