Lưu trữ và xử lí nhiều giá trị cùng dạng một cách dễ dàng.

1. Mục tiêu

  • Trình bày được khái niệm mảng
  • Giải thích được mục đích và ý nghĩa của mảng
  • Khai báo và sử dụng được mảng 1 chiều
  • Khai báo và sử dụng được mảng 2 chiều
  • Sử dụng được vòng lặp để duyệt mảng 1 chiều
  • Sử dụng được vòng lặp để duyệt mảng 2 chiều
  • Thực hiện được các thao tác cơ bản với mảng

2. Giới thiệu

Trong các tình huống thực tế, có nhiều trường hợp chúng ta phải lưu trữ nhiều dữ liệu. Chẳng hạn như lưu trữ danh sách tên của hàng trăm sinh viên, điểm thi của từng sinh viên, lưu trữ danh sách các sản phẩm, lưu trữ danh sách các bài hát trong một album. Nếu sử dụng biến để chứa những giá trị này, chúng ta sẽ phải khai báo hằng trăm biến, thậm chí là hằng nghìn biến, điều này gây ra nhiều khó khăn cho lập trình viên và gần như là không thực tế.

Trong những tình huống như vậy, chúng ta có thể sử dụng cấu trúc dữ liệu mảng để lưu trữ dữ liệu dễ dàng hơn.

Hoàn thành chương này, chúng ta có thể xây dựng các ứng dụng trong đó có lưu trữ và xử lý nhiều dữ liệu cùng dạng.

3. Mảng

Mảng là gì?

Mảng là một loại biến đặc biệt, được dùng để lưu trữ nhiều giá trị. Trong các trường hợp mà chúng ta cần lưu trữ một danh sách các giá trị, chẳng hạn như danh sách khách hàng, danh sách sản phẩm, danh sách cấu hình… thì mảng là một lựa chọn tốt.

Chẳng hạn, nếu chúng ta sử dụng biến bình thường để lưu 3 tên xe thì đoạn mã sẽ như sau:

1.	let car1 = "Toyota"
2.	let car2 = "Subaru"
3.	let car3 = "BMW"

Thử tưởng tượng, nếu chúng ta có danh sách 100 chiếc xe thì sẽ làm sao? Chẳng lẽ chúng ta lại đi khai báo 100 biến tương ứng. Điều này có vẻ không hợp lý chút nào.

Nếu chúng ta sử dụng mảng, mã nguồn của chúng ta sẽ được đơn giản hoá đi rất nhiều:

1.	let cars = ["Toyota", "Subaru", "BMW"]

Một mảng có thể chứa nhiều giá trị trong một biến duy nhất, và chúng ta có thể truy cập các giá trị thông qua chỉ số của nó.

Các thành phần của một mảng

Khi khai báo và làm việc với mảng, chúng ta cần biết các thành phần sau:

  • Tên mảng (name): Phải tuân thủ theo quy tắc đặt tên của biến.
  • Độ dài của mảng (length): Là số lượng giá trị mà mảng có.
  • Phần tử (item): Là một giá trị trong mảng.
  • Chỉ số (index): Là vị trí của một phần tử trong mảng

Ví dụ:

1.	 let cars = ["Toyota", "Subaru", "BMW"]

Trong ví dụ này:

  • Tên của mảng là: cars
  • Độ dài của mảng là: 3
  • Các phần tử của mảng là: “Toyota”, “Subaru” và “BMW”

Chỉ số của phần tử (item index) là vị trí của phần tử trong mảng. Chỉ số đầu tiên là 0, tiếp sau là 1, 2, 3… cho đến hết. Chỉ số của phần tử cuối cùng của mảng sẽ là length – 1. Trong đó length là độ dài của mảng. Chẳng hạn, nếu mảng có 6 phần tử thì chỉ số của phần tử cuối cùng sẽ là 5.

Ví dụ:

1.	 let cars = ["Toyota", "Subaru", "BMW"]
2.	 cars[0] // Toyota
3.	 cars[1] // Subaru

Cú pháp khai báo mảng

Javascript hỗ trợ một số cú pháp khác nhau để khai báo mảng.

Cách 1: Sử dụng dấu ngoặc vuông ([]):

Cú pháp:

1.	let arr = [element1, element2, element3]

Ví dụ:

1.	let arr = ["Toyota", "Subaru", "BMW"]

 Lưu ý:

Dấu cách, hoặc dấu xuống dòng không có ảnh hưởng gì tới việc khai báo mảng. Chẳng hạn, chúng ta có thể khai báo trên nhiều dòng như sau:

1.	let arr = [
2.	           "Toyota",
3.	           "Subaru",
4.	           "BMW"
5.	    ];

Cách 2: Sử dụng từ khóa new:

1.	let arr = new Array("Toyota", "Subaru", "BMW");

Việc sử dụng từ khóa new hay dấu ngoặc vuông đều cho kết quả như nhau. Thông thường thì cú pháp sử dụng dấu ngoặc vuông được sử dụng nhiều hơn do ngắn gọn, dễ đọc.

Lưu ý:

Khi khai báo mảng sử dụng từ khoá new, nếu chúng ta truyền vào một số thì số đó sẽ là độ dài của mảng. Ví dụ, new Array(5) thì sẽ tạo ra một mảng có 5 phần tử, và giá trị của cả 5 phần tử đều là undefined. Tuy nhiên, new Array(5, 10) thì lại tạo ra một mảng có 2 phần tử, phần tử đầu tiên có giá trị là 5 và phần tử thứ hai có giá trị là 10.

Truy xuất một phần tử của mảng

Để truy xuất đến một phần tử của mảng, chúng ta sử dụng tên mảng và chỉ số của phần tử đó.

Ví dụ:

Truy xuất đến phần tử đầu tiên của mảng cars:

1.	let toy = cars[0];

Chúng ta cũng có thể sử dụng cách tương tự để gán giá trị cho các phần tử của mảng.

Ví dụ:

Gán giá trị mới cho phần tử ở vị trí số 3 của mảng cars:

1.	cars[3] = "Hyundai";

Độ dài của mảng

Chúng ta sử dụng thuộc tính length để biết độ dài của mảng.

Ví dụ:

1.	let countOfCars = cars.length; // 4

Trong ví dụ trên, độ dài của mảng là 4.

Thêm phần tử vào mảng

Hàm push() được sử dụng để thêm một phần tử mới vào phần cuối của mảng.

Ví dụ:

1.	cars.push("Kia");
2.	console.log(cars[cars.length - 1]); //Kia

Hàm unshift() được sử dụng để thêm một phần tử mới và phần đầu của mảng. Ví dụ

1.	cars.unshift("Ferrari");
2.	console.log(cars[0]); //Ferrari

Xoá phần tử của mảng

Hàm pop() được sử dụng để xóa phần tử cuối cùng và trả về giá trị của phần tử đó.

Ví dụ:

1.	let cars = ["Toyota", "Subaru", "BMW"];
2.	console.log(cars.length); // 3
3.	let firstElement = cars.shift();
4.	console.log(cars.length); // 2
5.	console.log(firstElement); //Toyota

Sắp xếp mảng

Hàm sort() được sử dụng để sắp xếp các phần tử của mảng theo một trật tự nhất định.

Ví dụ:

1.	let cars = ["Toyota", "Subaru", "BMW"];
2.	cars.sort();
3.	console.log(cars); //[ "BMW", "Subaru", "Toyota" ]

Chúng ta cũng có thể đảo ngược trật tự của một mảng bằng cách sử dụng hàm reverse().

Ví dụ:

1.	let cars = ["Toyota", "Subaru", "BMW"];
2.	cars.sort();
3.	console.log(cars); //[ "BMW", "Subaru", "Toyota" ]
4.	cars.reverse();
5.	console.log(cars); //[ "Toyota", "Subaru", "BMW" ]

Mặc định, phương thức sort() sẽ so sánh các phần tử theo trật tự của các ký tự trong bảng chữ cái. Chẳng hạn, phần tử “Apple” sẽ được đưa lên trước phần tử “Banana”.

Tuy nhiên, điều này sẽ gây sai sót khi so sánh các chữ số, chẳng hạn, số 100 sẽ được đưa lên trước số 25 (bởi vì số 1 đứng trước số 2 trong bảng chữ cái). Trong trường hợp này, chúng ta cung cấp cho hàm sort() một hàm so sánh, để nó thực hiện đúng chức năng của mình.

Ví dụ:

1.	let points = [40, 100, 1, 5, 25, 10];
2.	points.sort(function (a, b) {
3.	    return a - b;
4.	}) //[ 1, 5, 10, 25, 40, 100 ]
5.	points.sort(function (a, b) {
6.	    return b - a;
7.	}) //[ 100, 40, 25, 10, 5, 1 ]

Lưu ý:

  • Hàm so sánh là một hàm có mục đích giúp so sánh 2 phần tử.
  • Hàm so sánh có 2 tham số
  • Hàm so sánh trả về giá trị kiểu số: âm (nhỏ hơn 0), dương (lớn hơn 0) và 0.
    • Âm có nghĩa là phần tử đầu nhỏ hơn phần tử sau
    • Dương có nghĩa là phần tử đầu lớn hơn phần tử sau
    • 0 có nghĩa là 2 phần tử bằng nhau

Xem tiếp Chương 4