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

แปลงอาร์เรย์ของอาร์เรย์เป็นอาร์เรย์ของอ็อบเจกต์ที่จัดกลุ่มด้วย JavaScript

สมมติว่าเรามีอาร์เรย์สองมิติที่เก็บข้อมูลเกี่ยวกับสีและผลไม้ดังนี้:

const data = [
  ['orange', 'fruit'],
  ['red', 'color'],
  ['green', 'color'],
  ['orange', 'color'],
  ['banana', 'fruit'],
  ['blue', 'color'],
  ['lemon', 'fruit'],
  ['mango', 'fruit'],
  ['lemon', 'color']
];

เราต้องเขียนฟังก์ชันที่รับอาร์เรย์นี้และคืนค่าอาร์เรย์ของอ็อบเจกต์ที่จัดกลุ่มผลไม้และสีตามหมวดหมู่ของมัน ในตัวอย่างนี้มีเพียงสองหมวดหมู่คือ 'fruit' และ 'color' ดังนั้นผลลัพธ์ที่คาดหวังคืออาร์เรย์ของอ็อบเจกต์สองตัว:

[
  {
    group: 'fruit',
    value: ['orange', 'banana', 'lemon', 'mango']
  },
  {
    group: 'color',
    value: ['red', 'green', 'orange', 'blue', 'lemon']
  }
]

หมายเหตุ: แม้ตัวอย่างนี้จะมีเพียงสองหมวดหมู่ แต่เราต้องเขียนโซลูชันที่ทำงานได้กับจำนวนหมวดหมู่แบบไดนามิก ไม่ได้จำกัดแค่สองหมวดหมู่เท่านั้น

วิธีแก้ปัญหา

เราจะใช้เมธอด Array.prototype.reduce() สำหรับแต่ละซับอาร์เรย์ เราจะตรวจสอบว่ามีกลุ่มที่ตรงกันอยู่แล้วหรือไม่ หากมี ให้เพิ่มค่าใหม่เข้าไปใน property value ของกลุ่มนั้น มิฉะนั้น ให้สร้างอ็อบเจกต์ใหม่สำหรับกลุ่มนั้นและเพิ่มเข้าไปในอาร์เรย์สะสม

ตัวอย่างโค้ด

const data = [
  ['orange', 'fruit'],
  ['red', 'color'],
  ['green', 'color'],
  ['orange', 'color'],
  ['banana', 'fruit'],
  ['blue', 'color'],
  ['lemon', 'fruit'],
  ['mango', 'fruit'],
  ['lemon', 'color']
];

const groupData = arr => {
  return arr.reduce((acc, val) => {
    const [value, groupName] = val;
    const groupIndex = acc.findIndex(el => el?.group === groupName);
    if (groupIndex !== -1) {
      acc[groupIndex].value.push(value);
    } else {
      acc.push({
        group: groupName,
        value: [value]
      });
    }
    return acc;
  }, []);
};

console.log(groupData(data));

ผลลัพธ์

ผลลัพธ์ในคอนโซลจะเป็นดังนี้:

[
  { group: 'fruit', value: ['orange', 'banana', 'lemon', 'mango'] },
  { group: 'color', value: ['red', 'green', 'orange', 'blue', 'lemon'] }
]