Array Flattening คืออะไร
การแปลงอาร์เรย์ซ้อนหลายระดับ (Nested Array) ให้กลายเป็นอาร์เรย์แบน (Flat Array) ความลึก 1 ระดับ
ตัวอย่าง
const arr = [1, 3, [5, 6, [7, [6, 5], 4], 3], [4]]; // Output: [1, 3, 5, 6, 7, 6, 5, 4, 3, 4]
โค้ดตัวอย่าง (Recursive)
const arr = [1, 3, [5, 6, [7, [6, 5], 4], 3], [4]];
const flattenArray = (arr = []) => {
const res = [];
for (let i = 0; i < arr.length; i++) {
const el = arr[i];
if (Array.isArray(el)) {
res.push(...flattenArray(el)); // Recursive call
} else {
res.push(el);
}
}
return res;
};
console.log(flattenArray(arr));
ผลลัพธ์
[1, 3, 5, 6, 7, 6, 5, 4, 3, 4]
วิธีทันสมัย (ES2019+)
1. Array.prototype.flat() - มาตรฐาน
// ระบุ depth (Infinity = ทุกชั้น) const flatModern = arr => arr.flat(Infinity); console.log([1, [2, [3, [4]]]].flat(Infinity)); // [1, 2, 3, 4] console.log([1, [2, [3]]].flat(2)); // [1, 2, 3] (depth 2) console.log([1, [2, [3]]].flat()); // [1, 2, [3]] (default depth 1)
2. flatMap() - Map แล้ว Flatten depth 1
// ใช้สำหรับ map แล้ว flatten ทีเดียว const arr = [1, 2, 3]; console.log(arr.flatMap(x => [x, x * 10])); // [1, 10, 2, 20, 3, 30]
โค้ด Iterative (ไม่ใช้ Recursion - กัน Stack Overflow)
const flattenIterative = (arr) => {
const stack = [...arr].reverse();
const result = [];
while (stack.length) {
const item = stack.pop();
if (Array.isArray(item)) {
stack.push(...item.reverse());
} else {
result.push(item);
}
}
return result;
};
Reducer Version
const flattenReduce = (arr) =>
arr.reduce((acc, val) =>
acc.concat(Array.isArray(val) ? flattenReduce(val) : val), []);
เปรียบเทียบ
| Method | Browser Support | Performance | Max Depth |
|---|---|---|---|
| flat(Infinity) | ES2019+ | Fast (Native) | Unlimited |
| Recursive | All | Medium | Call stack limit |
| Iterative | All | Fast | Unlimited |
| Reduce | All | Slower | Call stack limit |
ข้อควรระวัง
- Circular reference จะทำให้ Infinite Loop
- Sparse arrays (มีช่องว่าง) จะถูกเติม undefined
- Non-array iterables (Set, Map, arguments) ไม่ถูก flatten