Đã bao giờ bạn nghe đến từ làm phẳng mảng trong JS chưa (hay bất kể ngôn ngữ nào khác cũng được), trong thuật ngữ tiếng anh nó được gọi là flatten array. Flatten array/mảng là khi bạn đưa tất cả phần tử trong một mảng về cùng cấp độ với nhau, ví dụ mảng A chứa số 1 và chứa một mảng con B, trong mảng con B chứa số 2, làm phẳng sẽ đưa số 2 lên đứng ngang cấp với số 1, không còn mảng lồng nhau trong mảng A nữa. Lý thuyết khó hiểu của mình đấy. Ví dụ thực tế nè. À đúng rồi, xuyên suốt bài mình sẽ dùng từ flatten thay cho làm phẳng nha.
1 | var nested = [ 1, 2, [ 3, 4 ], [ 5 ] ]; |
Vậy nếu có 3 mảng lồng nhau thì thế nào nhỉ?
Thêm tham số độ sâu muốn flatten
Cú pháp: array.flat(<độ sâu>)
Ở ví dụ trên độ sâu (deep) của mảng là 1
bởi vì mảng nested
chứa bên trong nó mảng con mà mảng con này không chứa mảng con khác (kiểu giống gia phả, hoặc đa cấp á, tới 1 cấp là hết rồi á). Lúc này nếu chỉ gọi flat()
không thôi, mặc định nó sẽ nhận độ sâu là 1
chỉ làm phẳng 1 cấp độ.
Ví dụ:
1 | var nested = [ 1, 2, [ 3, 4 ], [ 5, [ 6, 7 ] ] ]; |
Để flatten tất cả phần tử, ta viết lại:
1 | var nested = [ 1, 2, [ 3, 4 ], [ 5, [ 6, 7 ] ] ]; |
Vậy nhở tớ không biết mảng đó có độ sâu bao nhiêu thì sao, chả nhẽ ngồi đếm ư, huhu, bao giờ mới đi dự hội được :v.
Flatten không cần biết sâu bao nhiêu
Khi không biết sâu bao nhiêu ta thường bảo nhau, nó sâu vô tận, trong JS có một cái tên chỉ điều đó, đó chính là Infinity
. Và đúng rồi như bạn nghĩ, chỉ cần pass Infinity
vào function flat
thôi là tất cả xong xuôi.
1 | const soDeep = [ [ 1, 2, [ 3, [ 4, [ 5, [ 6, [ 7 ] ] ] ] ], 8 ] ]; |
Ồ hóa ra nó gê vậy cơ à, xưa giờ đi làm phẳng toàn xài đệ quy với viết loạn xạ cả lên, nên khỏe nhờ.
Thực ra nó đây là tính năng mới trong ES10, và tất nhiên IE thì khỏi phải nói không hỗ trợ IE nhé.
Xài flat
với mảng có phần tử trống
Flat
hữu dụng trong khá nhiều trường hợp và đây là một ví dụ:
1 | var missingNumbers = [1, , 3, , 5]; |
Nó sẽ tự động loại bỏ empty slot (phần tử trống) trong array.
Giải pháp thay thế
ES6
Cách này chỉ có thể flatten ở 1 level thôi nha.
1 | var oneLevelDeep = [ [ 1, 2 ], [ 3 ] ]; |
Cũ, cũ hơn cả ES6
Cũng tương tự như trên, chỉ có thể flatten ở 1 level thôi.
1 | var oneLevelDeep = [ [1, 2], [3]]; |
Dùng reduce
và concat
(thực ra là đệ quy)
Đây là giải pháp đến từ MDN web doc các bạn tham khảo nhé.
1 | var arr1 = [ 1, 2, 3, [ 1, 2, 3, 4, [ 2, 3, 4 ] ] ]; |
Bài tập thực hành
Các bạn thử tìm hiểu vào giải bài nào xem sao nhé. Đề bài viết hàm tìm số 213 trong mảng.
1 | const haystack =[1, 4, [5,6,7, [8, 18, [34,177,[98,[210,[213]]]]]]]; |