Computer >> Máy Tính >  >> Lập trình >> Javascript

Phương pháp hiệu quả nhất để phân nhóm trên một mảng đối tượng - JavaScript

Giả sử, chúng ta có một mảng các đối tượng như thế này -

const arr = [
   { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
   { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" },
   { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
   { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" },
   { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
   { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" },
   { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
   { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
];

Chúng tôi được yêu cầu viết một hàm JavaScript lấy một mảng như vậy làm đối số đầu tiên.

Mục đích của chúng tôi là có thể nhóm mảng đã cho dựa trên nhiều hoặc một thuộc tính đơn lẻ (được biểu thị bằng đối số thứ hai, thứ ba.)

Do đó, nếu chúng tôi đã thực hiện theo Giai đoạn nhóm, chúng tôi sẽ nhận được -

const output = [
   { Phase: "Phase 1", Value: 50 },
   { Phase: "Phase 2", Value: 130 }
];

Và nếu chúng tôi đã thực hiện Giai đoạn / Bước theo nhóm, chúng tôi sẽ nhận được -

const output = [
   { Phase: "Phase 1", Step: "Step 1", Value: 15 },
   { Phase: "Phase 1", Step: "Step 2", Value: 35 },
   { Phase: "Phase 2", Step: "Step 1", Value: 55 },
   { Phase: "Phase 2", Step: "Step 2", Value: 75 }
];

Ví dụ

Mã cho điều này sẽ là -

const arr = [
   { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
   { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" },
   { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
   { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" },
   { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
   { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" },
   { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
   { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
];
const groupBy = (array, groups, valueKey) => {
   const map = new Map;
   groups = [].concat(groups);
   return array.reduce((acc, val) => {
      groups.reduce((accu, value, ind, { length }) => {
         let child;
         if (accu.has(val[value])) {
            return accu.get(val[value]);
         };
         if (ind + 1 === length) {
            child = Object
            .assign(...groups.map(value => ({ [value]: val[value]
            })), { [valueKey]: 0 });
            acc.push(child);
         }
         else {
            child = new Map;
         };
         accu.set(val[value], child);
         return child;
      }, map)[valueKey] += +val[valueKey];
      return acc;
   }, []);
};
console.log(groupBy(arr, 'Phase', 'Value'));
console.log(groupBy(arr, ['Phase', 'Step'], 'Value'));

Đầu ra

Và đầu ra trong bảng điều khiển sẽ là -

[ { Phase: 'Phase 1', Value: 50 }, { Phase: 'Phase 2', Value: 130 } ]
[
   { Phase: 'Phase 1', Step: 'Step 1', Value: 15 },
   { Phase: 'Phase 1', Step: 'Step 2', Value: 35 },
   { Phase: 'Phase 2', Step: 'Step 1', Value: 55 },
   { Phase: 'Phase 2', Step: 'Step 2', Value: 75 }
]