Có rất nhiều phương thức của mảng trong JavaScript. Nhờ đó, việc xử lý mảng trở nên dễ dàng hơn. Sau đây, mình sẽ tìm hiểu chi tiết về các phương thức xử lý mảng phổ biến nhất. Show
Các phương thức thêm/xóa phần tử mảngTrong bài viết Array là gì? Array trong JavaScript, mình đã giới thiệu 4 phương thức cơ bản của mảng là:
Ngoài ra, còn nhiều phương thức của mảng trong JavaScript nữa. Phương thức spliceLàm sao để xóa phần tử bất kỳ trong mảng? Dĩ nhiên, mảng trong JavaScript cũng là object. Nghĩa là bạn có thể dùng delete để xóa một phần tử bất kỳ trong mảng dựa vào chỉ số. let letters = ["a", "b", "c"]; delete letters[1]; console.log(letters[1]); console.log(letters.length); Vấn đề xảy ra là: mặc dù bạn đã xóa một phần tử trong mảng, nhưng độ dài của mảng length vẫn không đổi (bằng 3). Bởi vì, delete obj.key chỉ xóa giá trị của thuộc tính key trong object. Cái chúng ta mong muốn là: khi xóa phần tử của mảng thì độ dài mảng phải giảm đi. Đó chính là lý do phương thức splice ra đời. Phương thức arr.splice có thể xóa, thêm hoặc thay thế phần tử của mảng. Cú pháp phương thức splice là: arr.splice(start[, deleteCount, elem1,..., elemN]); Phương thức splice xử lý mảng tại vị trí có chỉ số start bằng cách: xóa đi deleteCount phần tử, rồi chèn thêm các phần tử elem1,... elemN vào đúng vị trí đó. Sau đó, trả về mảng của những phần tử bị xóa. Ví dụ xóa đi 1 phần tử tại vị trí 1: let letters = ["a", "b", "c"]; letters.splice(1, 1); console.log(letters); Ví dụ xóa đi 3 phần tử tại vị trí đầu tiên và thêm 2 phần tử khác: let letters = ["a", "b", "c"]; letters.splice(0, 3, "d", "e"); console.log(letters); Ví dụ trả về mảng các phần tử bị xóa: let letters = ["a", "b", "c"]; let arr = letters.splice(1, 2, "d"); console.log(letters); console.log(arr); Phương thức splice cũng có thể thêm phần tử vào mảng mà không cần xóa đi phần tử nào, bằng cách truyền vào giá trị deleteCount bằng 0. let letters = ["a", "b", "c"]; letters.splice("1", 0, "d", "e"); console.log(letters); Phương thức splice chấp nhận chỉ số âm. Nếu chỉ số âm thì thứ tự đếm là từ cuối lên đầu, ví dụ: let letters = ["a", "b", "c"]; letters.splice(-1, 0, "d", "e"); console.log(letters); Phương thức slicePhương thức arr.slice đơn giản hơn phương thức arr.splice. Cú pháp phương thức slice là: arr.slice([start], [end]); Phương thức này trả về mảng mới bằng cách copy mảng ban đầu từ vị trí start đến vị trí end (không bao gồm end). Cả hai giá trị start và end đều có thể âm, khi đó việc đếm được tính từ cuối của mảng. Phương thức của array arr.slice tương tự như phương thức của string str.slice, chỉ khác là trả về subarray chứ không phải là substring. let letters = ["a", "b", "c", "d"]; let arr1 = letters.slice(1, 3); console.log(arr1); let arr2 = letters.slice(-2); console.log(arr2); Phương thức concatPhương thức arr.concat trả về array mới bao gồm các giá trị của arr ban đầu, cộng thêm giá trị các phần tử trong array thêm vào hoặc các giá trị khác. Cú pháp phương thức arr.concat là: arr.concat(arg1, arg2,...) Phương thức này chấp nhận số lượng tham số tùy ý. Và giá trị của arg1, arg2,... có thể là mảng hoặc giá trị khác. Giả sử phần tử argN là mảng thì tất cả các phần tử trong mảng argN được sao chép. Ngược lại, nếu giá trị của argN không phải mảng thì giá trị của chính nó được copy vào mảng, ví dụ: let arr1 = [1, 2]; let arr2 = arr1.concat([3, 4]); console.log(arr2); let arr3 = arr1.concat([3, 4], [5, 6]); console.log(arr3); let arr4 = arr1.concat([3, 4], 5, 6); console.log(arr4); Bình thường, phương thức concat chỉ copy các phần tử từ mảng. Nhưng với các object khác, thậm chí là dạng array-like (có chỉ số và thuộc tính length) thì giá trị của object cũng được copy vào: let arr = [1, 2]; let arrayLike = { 0: "hello", length: 1, }; console.log(arr.concat(arrayLike)); Nhưng nếu object array-like đó có thuộc tính đặc biệt là Symbol.isConcatSpreadable thì cách xử lý hoàn toàn giống như của mảng bình thường: let arr = [1, 2]; let arrayLike = { 0: "hello", 1: "hi", length: 2, [Symbol.isConcatSpreadable]: true, }; console.log(arr.concat(arrayLike)); Phương thức duyệt mảng trong JavaScriptPhương thức của mảng trong JavaScript giúp duyệt tất cả các phần tử là: forEach. Phương thức này cho phép bạn thực hiện một hàm trên mỗi phần tử trong mảng với cú pháp: arr.forEach(function (item, index, array) { }); Trong đó:
Ví dụ: ["a", "b", "c"].forEach(function (item, index, array) { console.log(`item ${item} at index ${index} in array ${array}`); });
item a at index 0 in array a,b,c item b at index 1 in array a,b,c item c at index 2 in array a,b,c Để hiểu hơn về forEach, bạn có thể đọc thêm bài viết: JavaScript forEach là cái quái gì? Các phương thức tìm kiếm trong mảngSau đây mình sẽ tìm hiểu về các phương thức của mảng trong JavaScript giúp tìm kiếm. Phương thức indexOf, lastIndexOf và includesCác phương thức indexOf, lastIndexOf và includes có cú pháp và cách sử dụng tương tự như các phương thức cùng tên trong string.
Các ví dụ: let arr = [1, 0, 1, false]; console.log(arr.indexOf(0)); console.log(arr.indexOf(false)); console.log(arr.indexOf(null)); console.log(arr.indexOf(1)); console.log(arr.lastIndexOf(1)); console.log(arr.includes(1)); Chú ý: các phương thức trên thường sử dụng toán tử so sánh bằng nghiêm ngặt === để kiểm tra. Nếu bạn tìm kiếm false thì kết quả trả về là vị trí chính xác của false chứ không phải 0. Nếu bạn muốn kiểm tra sự tồn tại mà không quan tâm đến chỉ số thì nên dùng arr.includes. Một điểm khác nhau giữa arr.includes với arr.indexOf và arr.lastIndexOf là arr.includes có thể tìm chính xác NaN. let arr = [NaN]; console.log(arr.includes(NaN)); console.log(arr.indexOf(NaN)); console.log(arr.lastIndexOf(NaN)); Phương thức find và findIndexGiả sử bạn có một mảng các object. Làm sao để tìm kiếm object trong mảng thỏa mãn một số điều kiện cho trước? Để giải quyết vấn đề này, bạn có thể dùng phương thức arr.find hoặc arr.findIndex. Phương thức arr.find(fn) có cú pháp là: let result = arr.find(function (item, index, array) { }); Trong đó:
Phương thức arr.find(fn) tìm kiếm một phần tử trong mảng thỏa mãn hàm fn (nói cách khác là hàm fn trả về true) và trả về phần tử tìm được, ngược lại thì trả về undefined. Ví dụ tìm kiếm user có id === 2 trong một mảng: let users = [ { id: 1, name: "Alex" }, { id: 2, name: "John" }, { id: 3, name: "Anna" }, ]; let user = users.find((item) => item.id === 2); console.log(user.name); Trong ví dụ trên, hàm cung cấp cho phương thức find là arrow function (item) => item.id === 2 với một tham số item (các tham số còn lại không sử dụng). Phương thức arr.findIndex có cú pháp hoàn toàn giống với arr.find. Chỉ khác là, arr.findIndex trả về chỉ số của phần tử tìm thấy, ngược lại thì trả về -1, ví dụ: let users = [ { id: 1, name: "Alex" }, { id: 2, name: "John" }, { id: 3, name: "Anna" }, ]; let index = users.findIndex((item) => item.id === 2); console.log(index); Phương thức filterPhương thức arr.find và arr.findIndex chỉ tìm kiếm phần tử đầu tiên thỏa mãn. Để tìm kiếm nhiều phần tử thỏa mãn, bạn có thể dùng phương thức arr.filter. Cú pháp của arr.filter tương tự như arr.find và arr.findIndex: let results = arr.filter(function (item, index, array) { }); Phương thức arr.filter trả về một mảng các phần tử thỏa mãn, ngược lại thì trả về mảng rỗng: let users = [ { id: 1, name: "Alex" }, { id: 2, name: "John" }, { id: 3, name: "Anna" }, ]; let results = users.filter((item) => item.id <= 2); console.log(results.length); let others = users.filter((item) => item.id > 5); console.log(others.length); Các phương thức biến đổi mảngSau đây là các phương thức của mảng trong JavaScript giúp tạo mảng mới từ một mảng gốc hoặc thay đổi thứ tự của mảng gốc. Phương thức mapPhương thức arr.map là một trong những phương thức phổ biến nhất của mảng. Phương thức này thực hiện một hàm trên mỗi phần tử của mảng và trả về một mảng các kết quả với cú pháp là: let result = arr.map(function (item, index, array) { }); Ví dụ từ mảng các string, suy ra mảng các độ dài tương ứng là: let lengths = ["Dog", "Fish", "Elephant"].map((item) => item.length); console.log(lengths); Phương thức sortPhương thức arr.sort sắp xếp các phần tử trong mảng theo thứ tự. Phương thức này trả về mảng đã được sắp xếp. Tuy nhiên, mình thường bỏ qua giá trị trả về. Vì thực chất là chính arr đã bị thay đổi. Ví dụ: let arr = [1, 2, 15]; arr.sort(); console.log(arr); Kết quả trả về là mảng [1, 15, 2]. Bạn có thấy điểm bất thường gì ở đây không?
💡 Mặc định các phần tử được sắp xếp theo thứ tự string. Trong ví dụ trên, các phần tử được chuyển đổi kiểu dữ liệu về string để so sánh. Mà "1" < "2" là true. Nên kết quả như trên là đúng. Để sắp xếp theo tứ tự mong muốn, bạn cần truyền vào một hàm để so sánh. Ví dụ một hàm so sánh: function compare(a, b) { if (a > b) return 1; if (a == b) return 0; if (a < b) return -1; } Áp dụng hàm so sánh vào phương thức arr.sort để sắp xếp mảng số: let arr = [1, 2, 15]; arr.sort(function (a, b) { if (a > b) return 1; console.log(arr); Kết quả bây giờ đã đúng như mong muốn. Phương thức reversePhương thức arr.reverse giúp đảo ngược mảng gốc, ví dụ: let arr = [1, 2, 3, 4, 5]; arr.reverse(); console.log(arr); Phương thức split và joinPhương thức arr.split(delim) giúp tách string thành một mảng với giá trị dùng để phân tách là delim. Ví dụ phân tách string thành mảng dựa trên dấu phẩy ,: let str = "a,b,c,d"; let arr = str.split(","); console.log(arr); Phương thức arr.split còn có tham số thứ hai dùng để giới hạn chiều dài của mảng: let str = "a,b,c,d"; let arr = str.split(",", 2); console.log(arr); Phương thức arr.join xử lý ngược lại với phương thức arr.split. Phương thức này trả về một string bằng cách ghép các phần tử mảng với "một kí tự kết nối". Ví dụ ghép các phần tử mảng bởi dấu ,: let arr = ["a", "b", "c", "d"]; let str = arr.join(","); console.log(str); Phương thức reduce và reduceRightPhương thức arr.reduce và arr.reduceRight dùng để tính toán và trả về một giá trị duy nhất từ các phần tử mảng. Cú pháp phương thức reduce là: let value = arr.reduce( function (accumulator, item, index, array) { }, [initial] ); Trong đó:
Kết quả trả về của phương thức reduce chính là giá trị cuối cùng của accumulator. Ví dụ tính tổng các phần tử trong mảng: let arr = [1, 2, 3, 4, 5]; let result = arr.reduce((sum, current) => sum + current); console.log(result); Phương thức arr.reduceRight tương tự như phương thức arr.reduce, chỉ khác là thứ tự duyệt từ phải sang trái. Để biết thêm về arr.reduce, mời bạn tham khảo bài viết: Ứng dụng reduce trong mảng. Cách kiểm tra giá trị là mảngVì array bản chất là object, nên bạn không thể dùng typeof để xác định array. let arr = []; let obj = {}; console.log(typeof arr); console.log(typeof obj); Để giải quyết vấn đề trên, bạn có thể sử dụng phương thức Array.isArray(value). Phương thức này trả về true nếu value là mảng, ngược lại thì trả về false. let arr = []; let obj = {}; console.log(Array.isArray(arr)); console.log(Array.isArray(obj)); Tham số thisArgHầu hết các phương thức của mảng trong JavaScript đều có tham số cuối cùng là thisArg.
Tham số này không bắt buộc và ít sử dụng nên mình không nói đến trong các phần trên. Cú pháp đầy đủ các phương thức với thisArg là: arr.find(func, thisArg); arr.filter(func, thisArg); arr.map(func, thisArg); Giá trị của thisArg chính là giá trị của this ở trong hàm func. Ví dụ lọc các giá trị của mảng nằm trong đoạn từ min đến max: let arr = [1, 3, 5, 2, 6, 10, 4]; let boundary1 = { min: 1, max: 5, }; let boundary2 = { min: 3, max: 8, }; function filterFunc(item) { return item >= this.min && item <= this.max; } let ret1 = arr.filter(filterFunc, boundary1); let ret2 = arr.filter(filterFunc, boundary2); console.log(ret1); console.log(ret2); Tổng kếtSau đây là tổng kết một số phương thức của mảng trong JavaScript:
Để kiểm tra một giá trị là mảng, bạn sử dụng phương thức Array.isArray(value). Trên đây là các phương thức của mảng trong JavaScript mà mình thấy hay sử dụng nhất. Dĩ nhiên, còn nhiều phương thức khác nữa, bạn có thể tự tìm hiểu thêm tại các bài viết sau: |