как сгруппировать по массиву итоговой суммы объекта в javascript? - PullRequest
1 голос
/ 07 августа 2020

После того, как я использую reduce() для группировки объектов в массиве по месяцу-году:

let groupByMonth;
if (newlistTaskEvaluation) {
    groupDataByMonth = newlistTaskEvaluation.reduce((groups, item) => {
     groups[item.time] = [...groups[item.time] || [], item];
      return groups;
     }, {});
}

У меня есть массив объектов событий, отформатированный по месяцу-году группы следующим образом:

groupByMonth = {
    '7-2020': [ //july
        {
            time: "7-2020",
            task: [
                { code: "p1", value: 123 },
                { code: "p2", value: 234 },
            ]
        },
        {
            time: "7-2020",
            task: [
                { code: "p1", value: 345 },
                { code: "p2", value: 456 },
            ]
        },
    ],
    '8-2020': [ //august
        {
            time: "8-2020",
            task: [
                { code: "p1", value: 567 },
                { code: "p2", value: 678 },
            ]
        },
        {
            time: "8-2020",
            task: [
                { code: "p1", value: 789 },
                { code: "p2", value: 999 },
            ]
        },
    ]
}

Как сгруппировать объект массива по коду ключа, времени и общей сумме по значению?

Ожидаемый результат:

output = [
    {
        time: "7-2020", //total month 7-2020
        task: [
            { code: "p1", valueSum: 468 }, // 123 + 345
            { code: "p2", valueSum: 690 }, // 234 +456
        ] 
    },
    {
        time: "8-2020",
        task: [
            { code: "p1", valueSum: 1356 }, // 567 + 789
            { code: "p2", valueSum: 1677 }, // 999 +678
        ]
    }
]

Пожалуйста, помогите мне.

Ответы [ 2 ]

2 голосов
/ 07 августа 2020
    const groupByMonth = {
  "7-2020": [
    //july
    {
      time: "7-2020",
      task: [
        { code: "p1", value: 123 },
        { code: "p2", value: 234 },
      ],
    },
    {
      time: "7-2020",
      task: [
        { code: "p1", value: 345 },
        { code: "p2", value: 456 },
      ],
    },
  ],
  "8-2020": [
    //august
    {
      time: "8-2020",
      task: [
        { code: "p1", value: 567 },
        { code: "p2", value: 678 },
      ],
    },
    {
      time: "8-2020",
      task: [
        { code: "p1", value: 789 },
        { code: "p2", value: 999 },
      ],
    },
  ],
};

const result = Object.keys(groupByMonth).reduce((arr, key)=>{
  const task = (groupByMonth[key]).reduce((acc, rec) => {
    return [...acc, rec.task]
  }, [])
    const newObj = {time: key, task}
    return [...arr, newObj]
}, [])

console.log(JSON.stringify(result, 2, 2))

Вы можете получить ключи объекта и, когда вы перебираете их, обнаруживаете внутренние объекты, затем в каждом объекте используйте другое сокращение, чтобы получить задачи в этом типе данных, что вам нужно. для итераций я внезапно использую метод reduce () как швейцарский нож для работы с массивами.

2 голосов
/ 07 августа 2020

Вы можете попробовать что-то вроде этого

const output = Object.entries(groupByMonth).map(([time, datapoints]) => {
  const codes = {}
  const allTasks = datapoints.flatMap(point => point.task)
  for (const { code, value } of allTasks) {
    codes[code] = (codes[code] || 0) + value
  }
  return {
    time,
    tasks: Object.entries(codes).map(([code, value]) => ({ code, value }))
  }
}

Хотя одним недостатком является то, что временная сложность не идеальна из-за структуры данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...