Xử lý mảng với Underscore.js

Chắc hẳn mỗi chúng ta khi lập trình không ít thì nhiều phải làm việc với mảng, cho dù sử dụng bất kì ngôn ngữ nào. Và javascript cũng vậy, tuy nhiên mảng trong javascript không có nhiều phương thức hỗ trợ như tìm kiếm, sắp xếp… ta có thể tự viết những phương thức đó cho riêng mình. Tuy nhiên, bằng cách sử dụng thư viện underscore.js việc thao tác mảng sẽ trở nên đơn giản hơn bao giờ hết. Dưới đây là một số cách sử dụng underscore với mảng mà mình hay dùng.

underscore.js còn có nhiều hàm hỗ trợ khác các bạn có thể tìm hiểu thêm tại trang tài liệu của nó. Trong bài viết này chỉ giới thiệu đến các hàm làm việc với mảng hay được sử dụng.

underscore sử dụng dấu _ (gạch dưới) để làm định danh cho nó.

Cách gọi hàm của underscore

1
_.tenHam( các biến )

Các ví dụ dưới đây sẽ sử dụng mảng dogs làm mẫu

1
2
3
4
5
6
7
dogs = [
{ name: "bo", age: "1", color: "yellow" },
{ name: "ki", age: "2", color: "black" },
{ name: "kit", age: "1.5", color: "white" },
{ name: "rex", age: "3", color: "brown" },
{ name: "bin", age: "2", color: "yellow" },
]

Danh sách các hàm xử lý với mảng trong bài viết này

Lặp qua các phần tử trong mảng

1
_.each(list, iterator, [context])

Lặp qua các phẩn tử trong mảng, lấy giá trị của phần tử gởi vào hàm iterator . Các thao tác với phần tử được dyệt qua, chúng ta viết vào hàm iterator . Hàm iterator nhận được các tham số sau (element, index, list)

Ví dụ với hàm iterator đầy đủ tham số

1
2
3
4
5
6
7
8
9
10
11
12
13
_.each(dogs, function(dog, index, list) {
console.log(index + " - Name: " + dog.name);
});
/*
0 - Name: bo
1 - Name: ki
2 - Name: kit
3 - Name: rex
4 - Name: bin
*/
  • dog: chú cún được duyệt qua
  • index: vị trí của chú cún trong mảng
  • list: chính là mảng dogs

Ta có thể dùng _.each chỉ với 1 tham số trong hàm iterator

1
2
3
4
5
6
7
8
9
10
11
12
13
_.each(dogs, function(dog) {
console.log(dog.name + " is " + dog.age + " year(s) old.");
});
/*
bo is 1 year(s) old.
ki is 2 year(s) old.
kit is 1.5 year(s) old.
rex is 3 year(s) old.
bin is 2 year(s) old.
*/

Tìm một phần tử trong mảng

1
_.find(list, iterator, [context])

Tìm phần tử đầu tiên thỏa mãn điều kiện được định nghĩa trong iterator . Nếu tìm không thấy trả về undefined.

Tìm và hiển thị thông tin của chú cún có tên là rex

1
2
3
4
5
6
7
8
var rex = _.find(dogs, function(dog) { return dog.name == "rex"; });
console.log(rex);
/*
Object {name: "rex", age: "1", color: "yellow"}
*/

Tìm nhiều phần tử trong mảng

1
_.filter(list, iterator, [context])

Tìm và trả về một mảng các phần tử có giá trị thỏa mãn điều kiện được định nghĩ trong iterator .

1
2
3
4
5
6
7
8
9
10
11
var oldDogs = _.filter(dogs, function(dog) { return dog.age >= 2; });
_.each(oldDogs, function(dog) { console.log(dog.name + " - " + dog.age) });
/*
ki - 2
rex - 3
bin - 2
*/

Kiểm tra một phần tử có trong mảng hay không

1
_.contains(list, value)

Trả về true nếu giá trị cần tìm có trong mảng.

1
2
_.contains([1, 2, 3], 3) // => true
_.contains([1, 2, 3], 4) // => false

Tìm vị trí của một giá trị trong mảng

1
_.indexOf(array, value, [isSorted])

Tìm vị trí của một giá trị trong mảng, trả về -1 khi giá trị không có trong mảng. Nếu ta biết chắc mảng đã được sắp xếp trước, để tìm kiếm được nhanh hơn ta truyền giá trị true cho tham số isSorted

1
_.indexOf([1 ,2, 3], 3) // => 2

Tìm giá trị lớn nhất trong mảng

1
_.max(list, [iterator], [context])

Lấy giá trị lớn nhất trong mảng. Nếu iterator được truyền vào, thì giá trị của nó sẽ được sử dụng để đánh giá.

1
2
3
4
_.max([1, 2, 5, 3]) // => 5
_.max(dogs, function(dog) { return dog.age })
// => { name: "rex", age: "3", color: "brown" }

Tìm giá trị nhỏ nhất trong mảng

1
_.min(list, [iterator], [context])

Sắp xếp mảng

1
_.sortBy(list, iterator, [context])

Trả về một bản copy của mảng đã được sắp xếp theo tiêu chí của iterator . iterator cũng có thể là tên của một thuộc tính được dùng làm tiêu chí sắp xếp, ví dụ age

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
_.sortBy([2, 5, 1], function(num) { return num; }) // => [1, 2, 5]
_.sortBy([2, 5, 1], function(num) { return -num; }) // => [5, 2, 1]
_.sortBy(dogs, function(dog) { return -dog.age; })
/*
[
{name:"rex", age: 3 , color:"brown"},
{name:"ki", age: 2 , color:"black"},
{name:"bin", age: 2 , color:"yellow"},
{name:"kit", age: 1.5 , color:"white"},
{name:"bo", age: 1 ,color:"yellow"}
]
*/
_.sortBy(dogs, "age")
/*
[
{name:"bo", age: 1 ,color:"yellow"}
{name:"kit", age: 1.5 , color:"white"},
{name:"ki", age: 2 , color:"black"},
{name:"bin", age: 2 , color:"yellow"},
{name:"rex", age: 3 , color:"brown"},
]
*/
  • Chú ý: * Lệnh sắp xếp không làm thay đổi trực tiếp lên mảng mà chỉ tạo một bản copy của mảng và tiến hành sắp xếp trên đó. Để thực sự sắp xếp mảng ta phải gán mảng bằng giá trị đã sắp xếp.
1
dogs = _.sortBy(dogs, "age")

Đếm các phần tử trong mảng theo một tiêu chí nào đó

1
_.countBy(list, iterator, [context])

Đếm các phần tử trong mảng theo tiêu chí được định nghĩ trong iterator, trả về một mảng gồm giá trị của các tiêu chí và số lượng các phần tử thỏa mãn tiêu chí.

1
2
3
4
5
6
7
8
9
_.countBy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(num) {
return num % 3 == 0 ? "chiaHetCho3" : "khongChiaHetCho3";
});
// => {khongChiaHetCho3: 7, chiaHetCho3: 3}
_.countBy(dogs, function(dog) { return dog.color; })
// => {yellow: 2, black: 1, white: 1, brown: 1}

Đảo lộn các phần tử trong mảng

1
_.shuffle(list)

Trả về một bản copy của mảng với các giá trị đã được xáo trộn.

1
_.shuffle([1, 2, 3, 4]) //=> [2, 4, 3, 1]

Loại bỏ các phần tử lặp nhau trong mảng

1
_.uniq(array, [isSorted], [iterator])

Trả về một bản copy của mảng với cái phần tử trùng nhau đã được loại bỏ.

1
_.uniq([1, 2, 1, 3, 1, 4]); // => [1, 2, 3, 4]