Группировать массив объекта времени - PullRequest
1 голос
/ 13 января 2020

У меня есть требование сгруппировать массив объектов на основе временного интервала. Ввод выглядит следующим образом:

[
  {
    _id: {
      hour: 0,
      interval: '0'
    },
    time: '0:0',
    count: 10
  },
  {
    _id: {
      hour: 0,
      interval: '15'
    },
    time: '0:15',
    count: 5
  },
  {
    _id: {
      hour: 0,
      interval: '30'
    },
    time: '0:30',
    count: 1
  },
  {
    _id: {
      hour: 0,
      interval: '45'
    },
    time: '0:45',
    count: 2
  },
  {
    _id: {
      hour: 1,
      interval: '0'
    },
    time: '1:0',
    count: 4
  },
  {
    _id: {
      hour: 1,
      interval: '15'
    },
    time: '1:15',
    count: 3
  },
  {
    _id: {
      hour: 1,
      interval: '30'
    },
    time: '1:30',
    count: 5
  },
  {
    _id: {
      hour: 1,
      interval: '45'
    },
    time: '1:45',
    count: 1
  }
]

Мой желаемый вывод:

[
      {
        "time": "0",
        "0": 10,
        "15": 5
        "30": 1,
        "45": 2
      },
      {
        "time": "1",
        "0": 4,
        "15": 3
        "30": 5,
        "45": 1
      }
    ]

Я пытался использовать следующий код для группировки объектов, который работает до некоторой степени, но я застрял на что делать дальше:

const a = [ { _id: { hour: 0, interval: '0' }, time: '0:0', count: 10 }, { _id: { hour: 0, interval: '15' }, time: '0:15', count: 5 }, { _id: { hour: 0, interval: '30' }, time: '0:30', count: 1 }, { _id: { hour: 0, interval: '45' }, time: '0:45', count: 2 }, { _id: { hour: 1, interval: '0' }, time: '1:0', count: 4 }, { _id: { hour: 1, interval: '15' }, time: '1:15', count: 3 }, { _id: { hour: 1, interval: '30' }, time: '1:30', count: 5 }, { _id: { hour: 1, interval: '45' }, time: '1:45', count: 1 }]

var group = a.reduce((r, a) => {
  console.log("a", a);
  console.log('r', r);
  r[a._id.hour] = [...r[a._id.hour] || [], a];
  return r;
}, {});
console.log("group", group);

Ответы [ 3 ]

2 голосов
/ 13 января 2020

Проверьте, существует ли сначала объект с этим hour в объекте-аккумуляторе - если это не так, создайте его, затем присвойте count свойству [interval] этого объекта и получите Object.values в конце чтобы превратить его обратно в массив:

const input=[{_id:{hour:0,interval:"0"},time:"0:0",count:10},{_id:{hour:0,interval:"15"},time:"0:15",count:5},{_id:{hour:0,interval:"30"},time:"0:30",count:1},{_id:{hour:0,interval:"45"},time:"0:45",count:2},{_id:{hour:1,interval:"0"},time:"1:0",count:4},{_id:{hour:1,interval:"15"},time:"1:15",count:3},{_id:{hour:1,interval:"30"},time:"1:30",count:5},{_id:{hour:1,interval:"45"},time:"1:45",count:1}];

const groupedObj = {};
for (const { _id: { hour, interval }, count } of input) {
  if (!groupedObj[hour]) {
    groupedObj[hour] = { time: hour };
  }
  groupedObj[hour][interval] = count;
}
const output = Object.values(groupedObj);
console.log(output);
1 голос
/ 13 января 2020

Вы можете группировать объект методом reduce. Поэтому сначала нужно сгруппировать по hour, а затем просто добавить interval свойства из каждой итерации reduce метода к свойству hour:

const result = arr.reduce((a, c) => {
   a[c._id.hour] = a[c._id.hour] || {};
   a[c._id.hour].time = c._id.hour;
   a[c._id.hour][c._id.interval] = c.count;    
   return a;
 }, {})

 console.log(result);

Пример:

let arr = [
  {
    _id: {
      hour: 0,
      interval: '0'
    },
    time: '0:0',
    count: 10
  },
  {
    _id: {
      hour: 0,
      interval: '15'
    },
    time: '0:15',
    count: 5
  },
  {
    _id: {
      hour: 0,
      interval: '30'
    },
    time: '0:30',
    count: 1
  },
  {
    _id: {
      hour: 0,
      interval: '45'
    },
    time: '0:45',
    count: 2
  },
  {
    _id: {
      hour: 1,
      interval: '0'
    },
    time: '1:0',
    count: 4
  },
  {
    _id: {
      hour: 1,
      interval: '15'
    },
    time: '1:15',
    count: 3
  },
  {
    _id: {
      hour: 1,
      interval: '30'
    },
    time: '1:30',
    count: 5
  },
  {
    _id: {
      hour: 1,
      interval: '45'
    },
    time: '1:45',
    count: 1
  }
]


 const result = arr.reduce((a, c) => {
   a[c._id.hour] = a[c._id.hour] || {};
   a[c._id.hour].time = c._id.hour;
   a[c._id.hour][c._id.interval] = c.count;

   return a;
 }, {})

 console.log(result);
1 голос
/ 13 января 2020

Уменьшите массив и создайте объект для каждого _id.time. Назначьте текущий [interval] = count объекту. Получите записи и используйте Array.from() для преобразования записей в массив требуемой формы:

const arr = [{"_id":{"hour":0,"interval":"0"},"time":"0:0","count":10},{"_id":{"hour":0,"interval":"15"},"time":"0:15","count":5},{"_id":{"hour":0,"interval":"30"},"time":"0:30","count":1},{"_id":{"hour":0,"interval":"45"},"time":"0:45","count":2},{"_id":{"hour":1,"interval":"0"},"time":"1:0","count":4},{"_id":{"hour":1,"interval":"15"},"time":"1:15","count":3},{"_id":{"hour":1,"interval":"30"},"time":"1:30","count":5},{"_id":{"hour":1,"interval":"45"},"time":"1:45","count":1}];

// convert the entries to an array
const result = Array.from(Object.entries(
    arr.reduce((r, o) => {
      const { hour, interval } = o._id; // get the hour and interval
      
      if(!r[hour]) r[hour] =  {}; // create a the hour object
     
      r[hour][interval] = o.count; // add the interval and count
      
      return r;
    }, {})
  ), ([time, values]) => ({ time, ...values })); // generate the result objects

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