json - Loại bỏ các đối tượng trùng lặp với Underscore cho Javascript
Tôi có kiểu mảng như thế này:
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
Tôi muốn lọc nó để có:
var bar = [ { "a" : "1" }, { "b" : "2" }];
Tôi đã thử sử dụng _.uniq, nhưng tôi đoán vì { "a" : "1" } không bằng chính nó, nên nó không hoạt động. Có cách nào để cung cấp cho _.uniq một hàm equals được override không?
Câu trả lời #1
.uniq/.unique nhận một hàm gọi lại
var list = [{a:1,b:5},{a:1,c:5},{a:2},{a:3},{a:4},{a:3},{a:2}];
var uniqueList = _.uniq(list, function(item, key, a) {
return item.a;
});
// uniqueList = [Object {a=1, b=5}, Object {a=2}, Object {a=3}, Object {a=4}]
Ghi chú :
- Giá trị trả về của callback được sử dụng để so sánh
- Đối tượng so sánh đầu tiên với giá trị trả về duy nhất được sử dụng làm duy nhất
- underscorejs.org trình bày cách sử dụng mà không cần callback
- lodash.com hiển thị cách sử dụng
Một ví dụ khác: sử dụng callback để trích xuất các hãng xe, màu sắc từ một danh sách
Câu trả lời #2
Nếu bạn muốn loại bỏ các bản sao dựa trên một id, bạn có thể làm điều gì đó như sau:
var res = [
{id: 1, content: 'heeey'},
{id: 2, content: 'woah'},
{id: 1, content:'foo'},
{id: 1, content: 'heeey'},
];
var uniques = _.map(_.groupBy(res,function(doc){
return doc.id;
}),function(grouped){
return grouped[0];
});
//uniques
//[{id: 1, content: 'heeey'},{id: 2, content: 'woah'}]
Câu trả lời số 3
Triển khai câu trả lời của Shiplu.
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var x = _.uniq( _.collect( foo, function( x ){
return JSON.stringify( x );
}));
console.log( x ); // returns [ { "a" : "1" }, { "b" : "2" } ]
Câu trả lời #4
Khi tôi có một thuộc tính id, đây là cách tôi ưu tiên sử dụng dấu gạch dưới:
var x = [{i:2}, {i:2, x:42}, {i:4}, {i:3}];
_.chain(x).indexBy("i").values().value();
// > [{i:2, x:42}, {i:4}, {i:3}]
Câu trả lời #5
Sử dụng thư viện underscore unique sau đây hoạt động với tôi, tôi đang tạo danh sách duy nhất dựa trên _id sau đó trả về giá trị Chuỗi của _id:
var uniqueEntities = _.uniq(entities, function (item, key, a) {
return item._id.toString();
});
Câu trả lời số 6
Đây là một giải pháp đơn giản, sử dụng so sánh đối tượng sâu để kiểm tra các phần tử trùng lặp (mà không cần chuyển đổi sang JSON, điều này không hiệu quả và tạm bợ)
var newArr = _.filter(oldArr, function (element, index) {
// tests if the element has a duplicate in the rest of the array
for(index += 1; index < oldArr.length; index += 1) {
if (_.isEqual(element, oldArr[index])) {
return false;
}
}
return true;
});
Nó lọc tất cả các phần tử nếu chúng có bản sao xuất hiện sau trong mảng - sao cho phần tử trùng lặp cuối cùng được giữ lại.
Việc kiểm tra trùng lặp sử dụng _.isEqual thực hiện so sánh sâu tối ưu giữa hai đối tượng, xem tài liệu underscore isEqual để biết thêm thông tin.
chỉnh sửa: đã cập nhật để sử dụng _.filter vốn là cách tiếp cận gọn gàng hơn
Câu trả lời số 7
Tài liệu lodash 4.6.1 có ví dụ này về sự bằng nhau của khóa đối tượng:
_.uniqWith(objects, _.isEqual);https://lodash.com/docs#uniqWith
