Xử lý Array trong js

11/05/2021 - lượt xem
Chia sẻ
 
5/5 - (1 bình chọn)

Array – mảng là kiểu dữ liệu phổ biến trong mọi ngôn ngữ lập trình. Bài viết này hưỡng dẫn xử lý Array trong js làm sao để hiệu quả và đúng đắn nhất.

Trong bài viết sẽ hướng dẫn chi tiết các thao tác với mảng trong javascript. Việc này cũng giúp những bạn mới tiếp xúc với js cũng có thể xử lý Array một cách dễ dàng. Nếu bạn là một người có kinh nghiệm lập trình, bài viết này sẽ giúp bạn củng cố thêm kiến thức của mình.

Array trong javascript là gì?

Trong javascript, mảng được khai báo bởi cặp dấu ngoặc vuông [ ], các phần tử cách nhau bới dấu phẩy “,”. Mảng có thể lưu trữ mọi kiểu dữ liệu khác như String, Boolean, Number, Object, hoặc thậm chí là Array.

Ví dụ

const mixedTypedArray = [100, true, 'freeCodeCamp', {}];

Vị trí của phần tử trong mảng gọi là index. Trong Javascript, chỉ số index bắt đầu từ 0 và tăng dần.

Trong ví dụ trên, phần tử 100 có index là 0, true có index là 1.

Ngoài ra độ dài của mảng là số lượng phần tử trong mảng đó, ví dụ trên là 4.

Một chú ý khác, giống trong PHP, mảng của js không cố định chiều dài (định trước số phần tử) giống trong C, C++.

Khởi tạp mảng trong js

Chúng ta có thể khởi tạp mảng/array trong javascript bởi nhiều cách:

Cách 1

const salad = ['?', '?', '?', '?', '?', '?', '?'];

Cách 2

const salad = new Array('?', '?', '?', '?', '?', '?', '?');

Chú ý: nếu sử dụng new Array(2), bạn sẽ nhận được 1 array với độ dài là 2 với các phần tử trong nó là undefined, nhưng nếu sử dụng new Array(1,2) bạn sẽ nhận được array độ dài 2 với 2 phần tử là 1 và 2..

Ngoài ra còn 1 số cách có thể tạo array như là Array.of, Array.from, hay toán tử (…).

Thao tác lấy phần tử trong mảng javascript

Chúng ta sử dụng dựa trên chỉ số index của phần tử

const element = array[index];
const salad = ['?', '?', '?', '?', '?', '?', '?'];
salad[0]; // '?'
salad[2]; // '?'
salad[5]; // '?'
const salad = ['?', '?', '?', '?', '?', '?', '?'];
const len = salad.length;
salad[len - 1]; // '?'
salad[len - 3]; // '?'

Ngoài ra có thể sử dụng vòng for hoặc hàm forEach

const salad = ['?', '?', '?', '?', '?', '?', '?'];

for(let i=0; i<salad.length; i++) {
  console.log(`Element at index ${i} is ${salad[i]}`);
}

Kết quả là

Element at index 0 is ?
Element at index 1 is ?
Element at index 2 is ?
Element at index 3 is ?
Element at index 4 is ?
Element at index 5 is ?
Element at index 6 is ?

Thêm phần tử vào mảng trong js như thế nào?

Để thêm phần tử vào mảng, ta sử dụng hàm push.

const salad = ['?', '?', '?', '?', '?', '?', '?'];
salad.push('?');

Kết quả là

["?", "?", "?", "?", "?", "?", "?", "?"]

Hàm push sẽ thêm phần tử vào cuối của mảng. Trong trường hợp nếu muốn thêm phần tử vào đầu mảng trong javascript chúng ta sử dụng hàm unshift

const salad = ['?', '?', '?', '?', '?', '?', '?'];
salad.unshift('?');

Kết quả là

["?", "?", "?", "?", "?", "?", "?", "?"]

Xóa phần tử khỏi mảng trong js

Cách đơn giản nhất là dùng hàm pop. Hàm pop sẽ loại bỏ phần tử cuối của mảng, đồng thời trả về phần tử đó.

const salad = ['?', '?', '?', '?', '?', '?', '?'];
salad.pop(); // ?

console.log(salad); // ['?', '?', '?', '?', '?', '?']

Hàm shift sẽ loại bỏ phần tử đầu mảng và trả về phần tử đó.

const salad = ['?', '?', '?', '?', '?', '?', '?'];
salad.shift(); // ?

console.log(salad); // ['?', '?', '?', '?', '?', '?'];

Copy và Clone một mảng trong javascript như thế nào?

Chúng ta có thể dùng hàm slice. Hàm này sẽ tạo ra 1 mảng mới và copy từ mảng gốc.

const salad = ['?', '?', '?', '?', '?', '?', '?'];
const saladCopy = salad.slice();

console.log(saladCopy); // ['?', '?', '?', '?', '?', '?', '?']

salad === saladCopy; // returns false

Chúng ta có thể sử dụng toán tử … để thực hiện việc này. Nó sẽ đề cập trong phần tiếp theo của bài viết.

Kiểm tra biến có phải mảng trong js

Chúng ta sử dụng hàm isArray

Array.isArray(['?', '?', '?', '?', '?', '?', '?']); // returns true
Array.isArray('?'); // returns false
Array.isArray({ 'tomato': '?'}); // returns false
Array.isArray([]); // returns true

Detructuring mảng trong js

Với ES6 chúng ta có cấu trúc mới để extract thuộc tính (phần tử) của mảng thành các biến lưu giá trị. Việc làm này gọi là destructuring.

let [tomato, mushroom, carrot] = ['?', '?', '?'];
console.log(tomato, mushroom, carrot); // Output, ? ? ?

việc làm này tương đương với việc chúng ta lấy từng phần tử

let vegetables = ['?', '?', '?'];
let tomato = vegetables[0];
let mushroom= vegetables[1];
let carrot= vegetables[2];

Gán giá trị mặc định vào 1 biến

Khi sử dụng destructuring, khi không có giá trị tương ứng thì biến đó sẽ nhận undefined. Chúng ta có thể gán như sau.

let [tomato , mushroom = '?'] = ['?'];
console.log(tomato); // '?'
console.log(mushroom ); // '?'

Skip giá trị trong 1 mảng

Khi destructuring, bạn có thể bỏ qua phần tử mảng khi extract. Bài toán này hữu dụng khi bạn chỉ muốn chỉ lấy 1 số giá trị trong mảng.

t [tomato, , carrot] = ['?', '?', '?'];

console.log(tomato); // '?'
console.log(carrot); // '?'

Nested Array Destructuring trong js

Xem ví dụ dưới đây

let fruits = ['?', '?', '?', '?', ['?', '?', '?']];

Nếu ta muốn lấy giá trị ? ra khỏi Array thì cần phải làm thế nào?

Cách 1:

const veg = fruits[4]; // returns the array ['?', '?', '?']
const carrot = veg[2]; // returns '?'

Cách 2

fruits[4][2]; // returns '?

Hoặc cũng có thể dùng như dưới đây

let [,,,,[,,carrot]] = ['?', '?', '?', '?', ['?', '?', '?']];

Sử dụng Rest Parameter và cú pháp Spread trong Javascript

Từ ES6, chúng ta có thể sử dụng toán tử … (3 dấu chấm) cho Spread và Rest parameter trong destructuring array.

  • Với Rest Parameter, toán tử … xuất hiện bên trái cú pháp destructuring
  • Với Spread thì toán tử … xuất hiện bên phải cú pháp destructuring

Sử dụng với Rest Parameter trong js

Với Rest Parameter chúng ta có thể map các phần tử bên trái 1 mảng vào 1 mảng mới. Chú ý rằng cú pháp này chỉ áp dụng cho giá trị cuối cùng trong cú pháp destructuring.

const [tomato, mushroom, ...rest] = ['?', '?', '?', '?', '?', '?', '?'];

console.log(tomato); // '?'
console.log(mushroom); // '?'
console.log(rest); // ["?", "?", "?", "?", "?"]

Như ví dụ trên ta thấy rằng, các item ‘?’, ‘?’, ‘?’, ‘?’, ‘?’ sẽ được cho vào 1 array mới.

Sử dụng toán tử Spread trong js

const salad = ['?', '?', '?', '?', '?', '?', '?'];

const saladCloned = [...salad];
console.log(saladCloned); // ["?", "?", "?", "?", "?", "?", "?"]

salad === saladCloned // false

Khi sử dụng toán tư này, một mảng mới sẽ được copy từ mảng gốc ban đầu.

Vận dụng thực tế của Destructuring trong javascript

Sử dụng để swap giá trị với destructuring

Chúng ta có thể hoán đổi giá trị 2 biến bằng cách sử dụng cú pháp destructuring

let first = '?';
let second = '?';
[first, second] = [second, first];

console.log(first);  // '?'
console.log(second); // '?'

Sử dụng destructuring để gộp mảng

Ví dụ ta có 2 mảng như dưới đây

const emotion = ['?', '?'];
const veggies = ['?', '?', '?', '?'];

Chúng ta có thể merge 2 mảng trên bằng cách như sau

const emotionalVeggies = [...emotion, ...veggies];
console.log(emotionalVeggies); // ["?", "?", "?", "?", "?", "?"]

Các hàm thao tác với mảng trong javascript

Như phần bên trên đã đề cập, chúng ta đã biết tới các hàm như:

  • Hàm push() – chèn 1 phần tử vào cuối mảng
  • Hàm unshift() – chèn phần từ vào đầu mảng
  • Hàm pop() – xóa 1 phần tử khỏi cuối mảng
  • Hàm shift() – xóa 1 phần tử khỏi đầu mảng
  • Hàm slice() – Sử dụng copy mảng
  • Hàm Array.isArray() – Kiểm tra có phải mang hay không?
  • length – trả về kích cỡ của mảng

Hàm concat array trong js

Hàm concat dùng để merge 1 hay nhiều mảng và tgrar về một mảng đã được gộp lại. Mảng được trả về là mảng mới và không thay đổi giá trị mảng gốc ban đầu.

const first = [1, 2, 3];
const second = [4, 5, 6];

const merged = first.concat(second);

console.log(merged); // [1, 2, 3, 4, 5, 6]
console.log(first); // [1, 2, 3]
console.log(second); // [4, 5, 6]

hàm concat cũng có thể để merge nhiều mảng lại với nhau

const first = [1, 2, 3];
const second = [4, 5, 6];
const third = [7, 8, 9];

const merged = first.concat(second, third);

console.log(merged); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

Hàm join array

Hàm join cho phép nối các phần tử trong mảng lại thành chuỗi. Mặc định ký tự được dùng để nối các phần tử là dấu phẩy “,”.

const emotions = ['?', '?', '?', '?'];

const joined = emotions.join();
console.log(joined); // "?,?,?,?"

hoặc bạn có thể thay đổi ký tự nối này

const joined = emotions.join('<=>');
console.log(joined); // "?<=>?<=>?<=>?"

Nếu sử dụng hàm join cho một mảng rỗng, kết quả nhận được là chuỗi rỗng

[].join() // returns ""

Hàm fill array

Hàm fill sẽ lấp đầy (thay thế) một mảng với giá trị mặc định. Chúng ta cũng có thể xác định các phần tử sẽ bị thay thế.

const colors = ['red', 'blue', 'green'];

colors.fill('pink');
console.log(colors); // ["pink", "pink", "pink"]

Hoặc nếu chỉ muốn thay thế 2 phần tử cuối cùng

const colors = ['red', 'blue', 'green'];

colors.fill('pink', 1,3); // ["red", "pink", "pink"]

Trong đó, tham số đầu tiên của hàm là giá trị muốn thay thế, tham số thứ 2 là vị trí bắt đầu thay thế – bắt đầu từ 0. Tham số cuối cùng là chỉ khi nào sẽ dừng việc thay thế lại. Giá trị này tối đa là bằng colors.length.

Hàm includes array

Để xác định 1 phần tử có thuộc một mảng cho trước hay không ta sử dụng hàm includes. Nếu phần tử đó được tìm thấy, hàm đó sẽ trả về true, và false trong trường hợp ngược lại.

const names = ['tom', 'alex', 'bob', 'john'];

names.includes('tom'); // returns true
names.includes('july'); // returns false

Hàm indexof trong array

Nếu bạn muốn biết vị trí của 1 phần tử trong mảng, hãy sử dụng indexof. Nó sẽ trả về ví trí của phần tử trong mảng, nếu không tìm thấy, giá trị trả về là -1.

const names = ['tom', 'alex', 'bob', 'john'];

names.indexOf('alex'); // returns 1
names.indexOf('rob'); // returns -1

Một hàm khác là lastIndexOf() giúp bạn tìm được vị trí cuối cùng của phần tử trong mảng. Trong khi đó hàm indexOf chỉ trả về vị trí đầu tiên của phần. Nói cách khác hàm indexOf sẽ trả về vị trí dầu tiên nếu tại vị trí đó có giá trị bằng giá trị cần tìm.

const names = ['tom', 'alex', 'bob', 'tom'];

names.indexOf('tom'); // returns 0
names.lastIndexOf('tom'); // returns 3

Hàm reverse array

Hàm này dùng để đảo ngược mảng, phần tử đầu sẽ thành phần tử cuối và ngược lại.

const names = ['tom', 'alex', 'bob'];

names.reverse(); // returns ["bob", "alex", "tom"]

Chú ý rằng, hàm này sẽ sửa trực tiếp mảng gốc ban đầu.

Hàm sort array

Hàm sort là hàm dùng phổ biến trong việc xử lý mảng trong js. Mặc định, hàm sort sẽ chuyển các phần tử sang dạng string và sau đó sắp xếp chúng. Chiều mặc định sắp xếp là chiều tăng dần. Hàm sort cũng là hàm sẽ thay đổi mảng gốc ban đầu.

const names = ['tom', 'alex', 'bob'];

names.sort(); // returns ["alex", "bob", "tom"]

Ví dụ với 1 mảng là các số

const numbers = [23, 5, 100, 56, 9, 13, 37, 10, 1]
Khi sử dụng
numbers.sort();
kết quả là
[1, 10, 100, 13, 23, 37, 5, 56, 9]

Như ví dụ trên, thì đây không phải kết quả chúng ta mong muốn. Bởi lẽ hàm sort đã chuyển các số sang dạng String và so sánh chúng trong hệ mã UTF-16.

Để khắc phục trong trường hợp này ta truyền thêm 1 hàm callback vào trong hàm sort.

function ascendingComp(a, b){
  return (a-b);
}

Đưa hàm này vào trong hàm sort

numbers.sort(ascendingComp); // retruns [1, 5, 9, 10, 13, 23, 37, 56, 100]

/* 

We could also code it like,

numbers.sort(function(a, b) {
  return (a-b);
});

Or, with the arrow function,

numbers.sort((a, b) => (a-b));

*/

Nếu muốn sắp xếp theo chiều giảm dần thì

numbers.sort((a, b) => (b-a));

Hàm splice array

Hàm splice giúp bạn thêm, cập nhật hay xóa phần tử trong 1 mảng. Phương thức hơi khó hiểu hơn so với các phương thức khác.

Mục đích chính của hàm splice là xóa các phần tử khỏi mảng. Nó sẽ trả về mảng của các phần tử đã xóa và cập nhật trên mảng gốc. Tuy vậy bạn có thể dùng hàm này cho việc thêm hoặc thay thế các phần tử.

Để thêm phần tử sử dụng hàm splice, chúng ta cần đưa vào vị trí chúng ta muốn thêm, số lượng phần từ muốn xóa bắt đầu từ vị trí nào và các phần tử muốn thêm vào.

Ví dụ dưới đây sẽ thêm phần tử “zack” tại index = 1 mà không xóa bất kì phần tử nào

const names = ['tom', 'alex', 'bob'];

names.splice(1, 0, 'zack');

console.log(names); // ["tom", "zack", "alex", "bob"]

Ví dụ dưới đây sẽ xóa 1 phần tử từ index =2 (phần tử thứ 3), sau đso thêm 1 phần tử “zack”. Hàm splice trả về array với phần tử bị xóa “bob”

const names = ['tom', 'alex', 'bob'];

const deleted = names.splice(2, 1, 'zack');

console.log(deleted); // ["bob"]
console.log(names); // ["tom", "alex", "zack"]

Các phương thức tĩnh xử lý Array trong javascript

Hàm Array.from()

Hãy xem đoạn html dưới đây

<div id="main">
  <ul>
    <ol type="1">
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
      <li>...</li>
    </ol>
  </ul> 
</div>

Chúng ta sử dụng hàm getElementsByTagName để lấy ra toàn bộ li

document.getElementsByTagName('li');

Kết quả thu được là

HTMLCollection không phải là 1 array

Kết quả thu về trông rất giống một array phải không, hãy sử dụng hàm forEach nhé

document.getElementsByTagName('li').forEach(() => {
 // Do something here..
})

Khi chạy chúng ta sẽ nhận được lỗi bởi vì HTMLCollection không phải là 1 array, đó à một object Array-Like, do đó bạn không thể sử dụng forEach.

Array-like object

Lúc này chúng ta sử dụng hàm Array.from(), nó sẽ chuyển từ 1 object array-like về 1 array

const collection = Array.from(document.getElementsByTagName('li'))

Hàm Array.of()

Hàm Array.of sẽ tạo 1 mảng mới từ dữ liệu đầu vào, dữ liệu này có thể là bất kì kiểu dữ liệu nào và cũng không giới hạn số phần tử

Array.of(2, false, 'test', {'name': 'Alex'})

Kết quả là

Các hàm iterator array trong javascript

Những hàm iterator được sử dụng rất nhiều để duyệt mảng, thực hiện tính toán, lọc…

Cho một mảng students như sau:

let students = [
   {
      'id': 001,
      'f_name': 'Alex',
      'l_name': 'B',
      'gender': 'M',
      'married': false,
      'age': 22,
      'paid': 250,  
      'courses': ['JavaScript', 'React']
   },
   {
      'id': 002,
      'f_name': 'Ibrahim',
      'l_name': 'M',
      'gender': 'M',
      'married': true,
      'age': 32,
      'paid': 150,  
      'courses': ['JavaScript', 'PWA']
   },
   {
      'id': 003,
      'f_name': 'Rubi',
      'l_name': 'S',
      'gender': 'F',
      'married': false,
      'age': 27,
      'paid': 350,  
      'courses': ['Blogging', 'React', 'UX']
   },
   {
      'id': 004,
      'f_name': 'Zack',
      'l_name': 'F',
      'gender': 'M',
      'married': true,
      'age': 36,
      'paid': 250,  
      'courses': ['Git', 'React', 'Branding']
   } 
];

Hàm filter

hàm filter sẽ tạo ra một array mới với các phần tử thỏa mãn điều kiện trong hàm callback. Ví dụ hãy tìm tất cả các sinh viên có giới tính là F

const femaleStudents = students.filter((element, index) => {
  return element.gender === 'F';
})

console.log(femaleStudents);

Hàm map()

hàm map sẽ tạo ra một array mới duyệt qua các phần tử và áp dụng 1 biểu thức logic – biểu thức này được cung cấp qua 1 hàm callback.

Ví dụ tạo một mảng chứa full name của tất cả sinh viên

const fullNames = students.map((element, index) => {
  return {'fullName': element['f_name'] + ' ' + element['l_name']}
});

console.log(fullNames);

Kết quả là

Hàm reduce

Hàm reduce áp dụng 1 hàm reducer cho mỗi phần tử của mảng và trả về giá trị cuối cùng sau khi tính toán.

Ví dụ tính tổng tiền phải trả bởi của tất cả sinh viên

const total = students.reduce(
   (accumulator, student, currentIndex, array) => {
      accumulator = accumulator + student.paid;
      return (accumulator);
   }, 
0);

console.log(total); // 1000

Trong đoạn code trên

  • . accumulator được khởi tạo bằng 0
  • Chúng ta áp dụng hàm reduce cho mỗi đối tượng student. Đồng thời truy cập thuộc tính paid và thêm nó vào accumulator
  • Cuối cùng chúng ta trả về accumulator

 

Hàm some()

Hàm này trả về giá trị boolean (true/false) dựa trên dựa trên có ít nhất 1 phần tử của mảng thỏa mãn điều kiện của hàm.

Ví dụ kiểm tra xem có bất kì sinh viên nào ít hơn 30 tuổi không

let hasStudentBelow30 = students.some((element, index) => {
  return element.age < 30;
});

console.log(hasStudentBelow30); // true

Hàm find()

Sử dụng hàm some, chúng ta thấy rằng có ít nhất student nhỏ hơn 30 tuổi, vậy làm thế nào để tìm thấy student đó.

Khi đó chúng ta dùng hàm find, hàm find sẽ trả về phần tử đầu tiên thỏa mãn điều kiện.

Ngoài ra còn có hàm findIndex giống như find nhưng nó trả về index của phần tử tìm thấy. Nếu không có phần tử nào tìm thấy, hàm findIndex trả về -1.

const student = students.find((element, index) => {
  return element.age < 30;
});

console.log(student);

Kết quả là

Hàm every()

Hàm every kiểm tra xem mọi phần tử trong array có thỏa mãn điều kiện hay không

Ví dụ kiểm xem tất cả các student có đăng ký ít nhất 2 khóa học hay không?

const atLeastTwoCourses = students.every((elements, index) => {
  return elements.courses.length >= 2;
});

console.log(atLeastTwoCourses); // true

Hàm at()

Hàm at() giúp chúng ta truy cập phần tử thông qua chỉ số index, tuy vậy chỉ số index này có thể là số âm.

const junkFoodILove = ['?', '?', '?', '?', '?', '?', '?', '?'];

junkFoodILove.at(0); // ?
junkFoodILove.at(3); // ?
junkFoodILove.at(-1); // ?
junkFoodILove.at(-5); // ?
junkFoodILove.at(-8); // ?
junkFoodILove.at(10); // undefined

Bài viết được dịch từ https://www.freecodecamp.org/news/the-javascript-array-handbook/

Hi vọng sau bài viết này các bạn đã hiểu rõ hơn về array trong javascript. Từ đó có thể vận dụng tối đa cách sử dụng để đạt hiệu quả lớn nhất cho công việc của mình.

    Liên hệ với chúng tôi

    Để lại thông tin để nhận được các bài viết khác

    5/5 - (1 bình chọn)

    Xem thêm nhiều bài tin mới nhất về Frontend

    Xem thêm