aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Array.map và flatMap: giữ nhóm hay ghép thành một danh sách?

Suong Nguyen by Suong Nguyen
06/11/2026
in Đánh giá
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

API trả danh sách nhóm, mỗi nhóm có nhiều thành viên. Bạn cần lấy id để đưa vào một thao tác tiếp theo nhưng map tạo ra mảng lồng. flatMap phù hợp nếu sản phẩm cần ghép các kết quả con thành một danh sách; map phù hợp nếu ranh giới nhóm vẫn có ý nghĩa.

Bài đối chiếu MDN ngày 06/11/2026 và chạy ví dụ với Node.js 24.18.1. Kiểm tra dùng dữ liệu cục bộ, không gọi API hoặc benchmark tốc độ. Các mảng đầu vào trong bài là mảng đặc, không sửa cấu trúc mảng trong callback.

So sánh theo hình dạng đầu ra

Tiêu chí map flatMap
Callback trả về một mảng Giữ mảng ấy làm một phần tử Ghép các phần tử của mảng ấy
Số kết quả trên một đầu vào Một giá trị Có thể không có, một hoặc nhiều giá trị
Làm phẳng nhiều tầng Không Chỉ một cấp kết quả callback
Callback async Nhận các Promise Cũng nhận các Promise, không tự await
Dữ liệu gốc Không tự sửa Không tự sửa

Cột cuối không bảo đảm object bên trong bất biến. Callback của bạn vẫn có thể sửa object đang được tham chiếu. Hai phương thức giúp tạo mảng kết quả, không tự sao chép sâu toàn bộ dữ liệu.

1. Từ nhóm thành danh sách id

Lưu đoạn sau thành file .cjs và chạy Node. Ví dụ đặt nhóm rỗng ở giữa để kiểm tra nó được giữ hay bỏ đi:

const assert = require('node:assert/strict');
const groups = [
  {name: 'mobile', members: [{id: 1}, {id: 2}]},
  {name: 'empty', members: []},
  {name: 'backend', members: [{id: 3}]},
];

const groupedIds = groups.map(group => group.members.map(item => item.id));
const allIds = groups.flatMap(group => group.members.map(item => item.id));
assert.deepEqual(groupedIds, [[1, 2], [], [3]]);
assert.deepEqual(allIds, [1, 2, 3]);
assert.equal(groups.length, 3);

const oneLevel = [1, 2].flatMap(value => [[value, value * 10]]);
assert.deepEqual(oneLevel, [[1, 10], [2, 20]]);
console.log({groupedIds, allIds, oneLevel});

Ở allIds, mỗi callback trả một mảng id; flatMap ghép chúng thành kết quả chung. Ở oneLevel, callback trả một mảng chứa thêm mảng con, nên sau một lần làm phẳng vẫn còn mảng con. Không đọc chữ “flat” như cam kết mọi tầng đều được bỏ.

Nếu bước tiếp theo cần thông tin nhóm của từng id, việc ghép chỉ id đã làm mất ngữ cảnh đó. Có thể giữ map hoặc tạo object có cả groupName và memberId trước khi ghép. Hình dạng dữ liệu nên đi từ hợp đồng của nơi nhận, không đi từ mong muốn giảm số method.

2. Dùng mảng rỗng để loại kết quả

Một phần tử đầu vào có thể tạo không kết quả hoặc nhiều kết quả. Ví dụ độc lập sau tách các dòng chữ thành từ, bỏ dòng trắng:

const assert = require('node:assert/strict');
const lines = ['  Dart Flutter ', '', 'Node   SQLite'];
const words = lines.flatMap(line => {
  const trimmed = line.trim();
  return trimmed ? trimmed.split(/\s+/) : [];
});
assert.deepEqual(words, ['Dart', 'Flutter', 'Node', 'SQLite']);
assert.deepEqual([1, 2].flatMap(value => value === 1 ? [] : [value, value]), [2, 2]);

const promises = [1, 2].flatMap(async value => [value]);
assert.equal(promises.length, 2);
assert.ok(promises.every(value => value instanceof Promise));
console.log('words and async return shape verified');

Các Promise không trở thành mảng chỉ vì sau này chúng sẽ fulfilled bằng mảng. Muốn chạy callback async rồi ghép kết quả, cần một bước chờ theo chính sách xử lý lỗi của ứng dụng, sau đó mới làm phẳng những mảng đã có. flatMap không phải cơ chế điều phối tác vụ async.

Kiểm tra trước khi thay thế trong project

Đặt ca nhóm rỗng, một nhóm nhiều phần tử và nhiều nhóm liên tiếp. So sánh thứ tự id đầu ra với thứ tự dữ liệu đầu vào. Nếu dữ liệu API có members bằng null, quyết định reject hay chuẩn hóa tại biên; ví dụ không âm thầm coi mọi dữ liệu sai kiểu là mảng rỗng.

Nếu cần giữ object thành viên, thử sửa một object trong kết quả và xem nơi nào còn giữ cùng tham chiếu. Việc đó giúp nhóm hiểu rằng đổi map sang flatMap chỉ đổi cách ghép mảng, không tạo một bản sao object độc lập.

Tiêu chí chọn và giới hạn đánh giá

Dùng map khi mỗi đầu vào cần một kết quả và nhóm cần được bảo toàn. Dùng flatMap khi mỗi đầu vào sinh một mảng kết quả cần được ghép ngay một cấp. Với logic có nhiều nhánh, một vòng lặp rõ ràng có thể dễ bảo trì hơn callback dài.

Bài không kết luận phương thức nào nhanh hơn trên workload của bạn. Muốn chọn theo hiệu năng, đo dữ liệu, kích thước mảng và runtime thực tế sau khi đã xác nhận ngữ nghĩa tương đương. Trước hết hãy viết assertions về hình dạng đầu ra; đó là khác biệt có tác động trực tiếp đến đoạn code nhận kết quả.

Nguồn tham khảo

  • MDN: Array.prototype.flatMap
  • MDN: Array.prototype.map

Tags: ArrayJavaScriptXử lý dữ liệu
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

String.replace và replaceAll: thay một lần hay mọi lần, có giữ nguyên ký tự $ không?

by Suong Nguyen
07/11/2026
0

So sánh thay chuỗi bằng pattern string và RegExp, đồng thời dùng replacer function để giữ nguyên nội dung thay thế có $&.

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Promise.any và Promise.race: chờ thành công đầu tiên hay kết quả đầu tiên?

by Suong Nguyen
05/11/2026
0

So sánh any và race bằng promise điều khiển được, gồm lỗi đầu tiên, AggregateError và danh sách rỗng.

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Array.slice và splice: end index khác deleteCount thế nào?

by Suong Nguyen
04/11/2026
0

So sánh slice và splice bằng cùng một mảng để phân biệt khoảng lấy ra, số phần tử xóa, giá trị trả về và việc thay đổi mảng...

Minh họa kiến trúc backend API gọn gàng cho sản phẩm nhỏ

Array.some và every: chọn đúng câu hỏi, nhớ trường hợp mảng rỗng

by Suong Nguyen
03/11/2026
0

Kiểm chứng some và every bằng cùng bộ dữ liệu để phân biệt có ít nhất một, tất cả và điều kiện bắt buộc danh sách không rỗng.

Next Post
Minh họa các khái niệm AI, mạng nơ-ron và lập trình trên máy tính

Softmax: trừ max logit trước khi tính exp để tránh overflow

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native FlatList hai cột: numColumns không tạo layout masonry
  • JavaScript Set với object: cùng id vẫn có thể là hai phần tử
  • Android elapsedRealtime và uptimeMillis: thời gian máy ngủ có được tính không?

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply