Làm thế nào để loại bỏ object trùng lặp khỏi array trong Javascript

Tiếp nối bài viết trước của mình Làm thế nào loại bỏ phần tử trùng lặp khỏi array trong Javascript, hôm nay mình sẽ giới thiệu đến các bạn cách loại bỏ object trùng lặp ra khỏi một array trong Javascript (JS).

Code dành cho những bạn không muốn đọc dài dòng =)))).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var originalArray = [
{ id: 1, name: 'a' },
{ id: 3, name: 'b' },
{ id: 3, name: 'c' },
{ id: 2, name: 'd' },
{ id: 4, name: 'e' },
{ id: 2, name: 'f' },
];

var uniqueArray = originalArray
.map(v => v['id'])
.map((v, i, array) => array.indexOf(v) === i && i)
.filter(v => originalArray[v])
.map(v => originalArray[v]);

// Kết quả
// [
// { id: 1, name: "a" }
// { id: 3, name: "b" }
// { id: 2, name: "d" }
// { id: 4, name: "e" }
// ];

Quy trình giải quyết

Giả sử mình có mảng như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var animals = [
{ id: 1, name: "Ant" },
{ id: 2, name: "Antelope" },
{ id: 5, name: "Avocet" },
{ id: 4, name: "Badger" },
{ id: 6, name: "Camel" },
{ id: 10, name: "Coyote" },
{ id: 2, name: "Crocodile" },
{ id: 3, name: "Eagle" },
{ id: 7, name: "Falcon" },
{ id: 8, name: "Flamingo" },
{ id: 8, name: "Gecko" },
{ id: 5, name: "Guppy" },
{ id: 14, name: "Harrier" },
{ id: 9, name: "Iguana" },
{ id: 9, name: "Jaguar" },
{ id: 10, name: "Jellyfish" },
{ id: 9, name: "Kingfisher" },
{ id: 13, name: "Lion" },
{ id: 10, name: "Panther" },
{ id: 5, name: "Badger" },
{ id: 1, name: "Macaw" },
{ id: 5, name: "Nightingale" },
{ id: 6, name: "Octopus" },
{ id: 11, name: "Otter" },
{ id: 12, name: "Octopus" },
{ id: 15, name: "Otter" }
];

Như bạn có thể thấy, mảng animals này chứa 26 objects với mỗi object có properties là idname, và id bị trùng lặp trong mảng khá nhiều. Và bạn muốn loại bỏ những object có id bị lặp lại.

Để thực hiện điều này thì ý tưởng sẽ như sau:

  1. Đầu tiên sẽ tạo một mảng tạm chỉ chứa id của object. Ví dụ [1, 2, 1, 3, 2, 10, ...].
  2. Kiểm tra xem id nào bị lặp lại, nếu lặp lại thì đánh dấu ngay chỗ index của nó bằng false hoặc null, undefined gì gì cũng được, nếu là duy nhất thì trả về lại index của nó. Ví dụ [0, 1, 2, 3, 4, 5, false, 7, 8, 9, false, ...].
  3. Loại bỏ hết false ra khỏi mảng tạm, lúc này mảng tạm chỉ chứa index của object có id duy nhất mà thôi.
  4. Cuối cùng lấy ra object có index trong bảng tạm.

Chúng ta sẽ sử dụng hai method có sẵn trong JS đó là mapfilter để thực hiện điều này (yêu cầu phải hiểu cách map và filter hoạt động). Oke let’s go.

Thực hiện

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// step 1
let uniqueAnimalsId = animals.map(v => v['id']);
// kết quả: [1, 2, 5, 4, 6, 10, 2, 3, 7, 8, 8, 5, 14, 9, 9, 10, 9, 13, 10, 5, 1, 5, 6, 11, 12, 15]

// step 2
// Dùng indexOf kiểm tra xem index của `v` có khớp với index của chính nó không
// nếu không khớp nghĩa là nó đã bị trùng
// chỗ này `array.indexOf(v) === i && i` là cách viết nhanh -> nếu `array.indexOf(v) === i` bằng true -> thực hiện vế sau trả về i
uniqueAnimalsId = uniqueAnimalsId.map((v, i, array) => array.indexOf(v) === i && i);
// kết quả: [0, 1, 2, 3, 4, 5, false, 7, 8, 9, false, false, 12, 13, false, false, false, 17, false, false, false, false, false, 23, 24, 25]

// step 3
// Lọc hết false đi, lấy id
uniqueAnimalsId = uniqueAnimalsId.filter(v => animals[v]);
// kết quả: [0, 1, 2, 3, 4, 5, 7, 8, 9, 12, 13, 17, 23, 24, 25]

// step 4
let uniqueAnimals = uniqueAnimalsId.map(v => animals[v]);

// kết quả cuối cùng
// uniqueAnimals = [
// { id: 1, name: "Ant" }
// { id: 2, name: "Antelope" }
// { id: 5, name: "Avocet" }
// { id: 4, name: "Badger" }
// { id: 6, name: "Camel" }
// { id: 10, name: "Coyote" }
// { id: 3, name: "Eagle" }
// { id: 7, name: "Falcon" }
// { id: 8, name: "Flamingo" }
// { id: 14, name: "Harrier" }
// { id: 9, name: "Iguana" }
// { id: 13, name: "Lion" }
// { id: 11, name: "Otter" }
// { id: 12, name: "Octopus" }
// { id: 15, name: "Otter" }
// ];

Viết dài dòng dùng cú pháp bình thường siêu rõ ràng thì sẽ như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// step 1
let uniqueAnimalsId = animals.map(function (value) {
// Có vài trường hợp đặc biệt bạn cần return về một string
// trường hợp đặt biệt ví dụ như id là date, ...
// ép về kiểu string: '' + value['id']
return value['id'];
});

// step 2
uniqueAnimalsId = uniqueAnimalsId.map(function (value, index, array) {
if (array.indexOf(value) === index) {
return index;
}
// nếu không return thì map sẽ map undefinded
return false;
});

// step 3
uniqueAnimalsId = uniqueAnimalsId.filter(function (value) {
return animals[value];
});

// step 4
let uniqueAnimals = uniqueAnimalsId.map(function (value) {
return animals[value];
});

// kết quả như trên.

Viết ngắn gọn lại:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let uniqueAnimals = animals
.map(v => v['id'])
.map((v, i, array) => array.indexOf(v) === i && i)
.filter(v => animals[v])
.map(v => animals[v]);

// uniqueAnimals = [
// { id: 1, name: "Ant" }
// { id: 2, name: "Antelope" }
// { id: 5, name: "Avocet" }
// { id: 4, name: "Badger" }
// { id: 6, name: "Camel" }
// { id: 10, name: "Coyote" }
// { id: 3, name: "Eagle" }
// { id: 7, name: "Falcon" }
// { id: 8, name: "Flamingo" }
// { id: 14, name: "Harrier" }
// { id: 9, name: "Iguana" }
// { id: 13, name: "Lion" }
// { id: 11, name: "Otter" }
// { id: 12, name: "Octopus" }
// { id: 15, name: "Otter" }
// ];

Tóm lại

Mình có vài lưu ý nhỏ như sau:

  1. Nếu viết dài dòng (tạo mảng tạm) thì sẽ tạo ra mảng có độ dài tương đương mảng gốc, nếu với dữ liệu lớn xử lý sẽ hơi chậm.
  2. Chỗ map(v => v['id']) bạn có thể thay id bằng property khác của object, name chẳng hạn, thì lúc này nó sẽ check xem name có trùng lặp hay không.
  3. Nếu kiểm tra duplicate với 2 property thì sẽ như thế nào nhỉ :)). Bạn đọc thử suy nghĩ thử xem nào.

À bạn biết name trong mảng animals kia hông. Mình post lên đây lun nhé, tranh thủ luyện tiếng anh tý đó mà :))

Ant 🐜: con kiến
Antelope 🦌: linh dương (chắc giống con deer, hươu)
Avocet: giống loài chim gì đó giống cò mà đẹp hơn cò nhiều (search wiki là thấy)
Badger 🦡: con lửng
Camel 🐪: lạc đà
Coyote 🐺: chó sói (sói ngoài đồng cỏ)
Crocodile 🐊: cá sấu
Eagle 🦅: đại bàng
Falcon: chim ưng
Flamingo 🦩: chim hồng hạc
Gecko 🦎: con thạch sùng hay tắc kè chi đó (còn tên khác là lizard)
Guppy: cá bảy màu hoặc cá đẹp đẹp nhiều màu cũng được
Harrier: tên chung chỉ các loại chim phá hoại như diều hâu (Hen harrier, Northern harrier, …)
Iguana: con kỳ nhông
Jaguar 🐆: báo đốm (cũng là tên loại xe thì phải) ngoài ra còn có tên leopard
Jellyfish: sứa
Kingfisher: chim bói cá
Lion 🦁: sư tử
Panther: báo đen
Macaw 🦜: vẹt tên khác là parrot
Nightingale: họa mi
Octopus 🐙: bạch tuột
Otter 🦦: rái cá
Flamingo guppy: cá hồng hạc :v

Tham khảo

 Comments
Comment plugin failed to load
Loading comment plugin