按日期分组数组,并计算平均值

时间:2017-11-05 21:00:04

标签: javascript arrays object

我有下面的数组,我想按天分组,然后计算平均血液读数。

[ { user: '59fcced3c40317c657878b5c',
    timestamp: 1509715440,
    blood: 8.2,
    id: '59fc6e42c6bc1c0223757c8e' },
  { user: '59fcced3c40317c657878b5c',
    timestamp: 1509698760,
    blood: 13.7,
    id: '59fc5c755109756616d29b49' },
  { user: '59fcced3c40317c657878b5c',
    timestamp: 1509694440,
    blood: 7.2,
    id: '59fc5ba65109756616d29b48' },
  { user: '59fcced3c40317c657878b5c',
    timestamp: 1509692580,
    blood: 3.4,
    id: '59fc5b915109756616d29b47' },
  { user: '59fcced3c40317c657878b5c',
    timestamp: 1509665040,
    blood: 8.7,
    id: '59fc4cf98e66f1e0065f4ff6' }]

我已经成功地将它分组,但我不能为我的生活找到如何进一步:

 let object = _.groupBy(results, (result) => moment.unix(result['timestamp']).startOf('day'));

我在jsfiddle中获得了代码:https://jsfiddle.net/0yn900jb

2 个答案:

答案 0 :(得分:1)

您可以使用Array#reduce将值收集到Map,并将日期字符串(删除时间后)作为键。然后Array#map将结果返回给对象,并计算平均值。

注意:我已将时间戳更改为显示2天。



const data = [{"user":"59fcced3c40317c657878b5c","timestamp":1509715440,"blood":8.2,"id":"59fc6e42c6bc1c0223757c8e"},{"user":"59fcced3c40317c657878b5c","timestamp":1509698760,"blood":13.7,"id":"59fc5c755109756616d29b49"},{"user":"59fcced3c40317c657878b5c","timestamp":1509694440,"blood":7.2,"id":"59fc5ba65109756616d29b48"},{"user":"59fcced3c40317c657878b5c","timestamp":1509573320,"blood":3.4,"id":"59fc5b915109756616d29b47"},{"user":"59fcced3c40317c657878b5c","timestamp":1509573320,"blood":8.7,"id":"59fc4cf98e66f1e0065f4ff6"}];

const averages = [...data.reduce((m, o) => {
  const date = new Date(o.timestamp * 1000); // create a date from time stamp
  const day = new Date(date.getFullYear(), date.getMonth(), date.getDate()); // create the day date

    const item = m.get(day.toLocaleDateString()) || { day, blood: [] }; // get the item from the map by the date string, or create a new one

    item.blood.push(o.blood); // add the blood number

    return m.set(day.toLocaleDateString(), item); // store the item by the time  string
  }, new Map).values()] // spread the map to an array of values
  .map(({ day, blood }) => ({ // map the array to and object
    day,
    blood: blood.reduce((a, b) => a + b) / blood.length // calculate bloody average
  }));

console.log(averages);




答案 1 :(得分:1)

您可以按如下方式扩展您的lodash解决方案:

let results = [ { user: '59fcced3c40317c657878b5c', timestamp: 1509715440, blood: 8.2, id: '59fc6e42c6bc1c0223757c8e' }, { user: '59fcced3c40317c657878b5c', timestamp: 1509698760, blood: 13.7, id: '59fc5c755109756616d29b49' }, { user: '59fcced3c40317c657878b5c', timestamp: 1509694440, blood: 7.2, id: '59fc5ba65109756616d29b48' }, { user: '59fcced3c40317c657878b5c', timestamp: 1509692580, blood: 3.4, id: '59fc5b915109756616d29b47' }, { user: '59fcced3c40317c657878b5c', timestamp: 1509665040, blood: 8.7, id: '59fc4cf98e66f1e0065f4ff6' }];
    
let object = _.chain(results)
    .groupBy((result) => moment.unix(result['timestamp']).startOf('day'))
    .map((entries, day) => [day, _.meanBy(entries, entry => entry.blood)])
    .fromPairs()
    .value();

console.log(object);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>