Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

Flatten อาร์เรย์ซ้อนหลายชั้น (Deep Flatten) ใน JavaScript

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), []);

เปรียบเทียบ

MethodBrowser SupportPerformanceMax Depth
flat(Infinity)ES2019+Fast (Native)Unlimited
RecursiveAllMediumCall stack limit
IterativeAllFastUnlimited
ReduceAllSlowerCall stack limit

ข้อควรระวัง

  • Circular reference จะทำให้ Infinite Loop
  • Sparse arrays (มีช่องว่าง) จะถูกเติม undefined
  • Non-array iterables (Set, Map, arguments) ไม่ถูก flatten