สมมติว่าเรามีอาร์เรย์สองมิติที่มีข้อมูลเกี่ยวกับสีและผลไม้บางอย่างเช่นนี้
const data = [ ['orange', 'fruit'], ['red', 'color'], ['green', 'color'], ['orange', 'color'], ['banana', 'fruit'], ['blue', 'color'], ['lemon', 'fruit'], ['mango', 'fruit'], ['lemon', 'color'], ];
เราต้องเขียนฟังก์ชันที่ใช้อาร์เรย์นี้และส่งกลับอาร์เรย์ที่มีการจัดกลุ่มผลไม้และสีต่างๆ ตามหมวดหมู่
เช่นเดียวกับในตัวอย่างนี้ เรามีเพียงสองประเภทเท่านั้นคือ 'ผลไม้' และ 'สี' ดังนั้นเราจึงควรคาดหวังอาร์เรย์ของสองวัตถุในผลลัพธ์เช่นนี้ -
[ { group: 'fruit', value: [ 'orange', 'banana', 'lemon', 'mango' ] }, { group: 'color', value: [ 'red', 'green', 'orange', 'blue', 'lemon' ] } ]
หมายเหตุ − ในตัวอย่างนี้ เรามีเพียงสองหมวดหมู่เท่านั้น แต่เราต้องเขียนโซลูชันที่ใช้ได้กับหมวดหมู่ที่มีจำนวนแบบไดนามิก ไม่ใช่แค่เพียงสองหมวดหมู่เท่านั้น
เรามาคิดวิธีแก้ปัญหานี้กัน เราจะใช้เมธอด Array.prototype.reduce() และสำหรับอาร์เรย์ย่อยแต่ละอัน เราจะตรวจสอบว่าเรามีกลุ่มที่มีอยู่หรือไม่ หากกลุ่มมีอยู่ เราจะผลักค่าใหม่เข้าไปในคุณสมบัติค่า มิฉะนั้นเราจะสร้างวัตถุใหม่สำหรับกลุ่มนั้นและพุชเข้าไปในอาร์เรย์
ตัวอย่าง
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' ] } ]