合并不同长度的对象

时间:2017-09-20 19:14:00

标签: javascript underscore.js

我有一个对象数组,用日期字符串键入,如下所示:

Loaded plugins: priorities, update-motd, upgrade-helper No matches found

我需要对每个对象中的所有值求和。所以最后,我需要一个看起来像这样的对象:

[
    {
        '2017-08-21': {row: 0, artind: 25, qind: 20}, 
        '2017-08-22': {row: 1, artind: 5, qind: 12}, 
        '2017-08-23': {row: 11, artind: 3, qind: 0}, 
        '2017-08-24': {row: 45, artind: 25, qind: 43}, 
        '2017-08-25': {row: 13, artind: 0, qind: 27}, 
        '2017-08-26': {row: 2, artind: 2, qind: 2}, 
        '2017-08-27': {row: 1, artind: 12, qind: 27}, 
        '2017-08-28': {row: 19, artind: 0, qind: 0}, 
        '2017-08-29': {row: 11, artind: 25, qind: 7}
    },
    {
        '2017-08-24': {row: 1, artind: 34, qind: 8}, 
        '2017-08-25': {row: 0, artind: 5, qind: 3}, 
        '2017-08-26': {row: 7, artind: 22, qind: 0}
    },
    {
        '2017-08-22': {row: 55, artind: 5, qind: 2}, 
        '2017-08-23': {row: 13, artind: 25, qind: 0}, 
        '2017-08-24': {row: 1, artind: 0, qind: 0}, 
        '2017-08-25': {row: 6, artind: 8, qind: 0}, 
        '2017-08-26': {row: 0, artind: 12, qind: 89}, 
        '2017-08-27': {row: 11, artind: 29, qind: 5}
    }
]

我真正用于支持的唯一库是underscore.js,所以这些答案肯定受到赞赏!

由于

4 个答案:

答案 0 :(得分:1)

您可以使用以下简化方法来解决您的问题。

const a = [{
  '2017-08-21': { row: 0, artind: 25, qind: 20 },
  '2017-08-22': { row: 1, artind: 5, qind: 12 },
  '2017-08-23': { row: 11, artind: 3, qind: 0 },
  '2017-08-24': { row: 45, artind: 25, qind: 43 },
  '2017-08-25': { row: 13, artind: 0, qind: 27 },
  '2017-08-26': { row: 2, artind: 2, qind: 2 },
  '2017-08-27': { row: 1, artind: 12, qind: 27 },
  '2017-08-28': { row: 19, artind: 0, qind: 0 },
  '2017-08-29': { row: 11, artind: 25, qind: 7 }
},
{
  '2017-08-24': { row: 1, artind: 34, qind: 8 },
  '2017-08-25': { row: 0, artind: 5, qind: 3 },
  '2017-08-26': { row: 7, artind: 22, qind: 0 }
},
{
  '2017-08-22': { row: 55, artind: 5, qind: 2 },
  '2017-08-23': { row: 13, artind: 25, qind: 0 },
  '2017-08-24': { row: 1, artind: 0, qind: 0 },
  '2017-08-25': { row: 6, artind: 8, qind: 0 },
  '2017-08-26': { row: 0, artind: 12, qind: 89 },
  '2017-08-27': { row: 11, artind: 29, qind: 5 }
}];

a.reduce((result, item) => {
  Object.keys(item).forEach((key) => {
    if (result[key]) {
      result[key] = {
        row: result[key].row + item[key].row,
        artind: result[key].artind + item[key].artind,
        qind: result[key].qind + item[key].qind };
    } else {
      result[key] = item[key];
    }
  });
  return result;
}, {});

编辑:正在制作

答案 1 :(得分:0)

我不确定这是最好的方式,但这就是我的方式。

我们假设变量detain包含您的数据,dataout是您的输出。

var datain = [
  {
    '2017-08-21': {row: 0, artind: 25, qind: 20},
    '2017-08-22': {row: 1, artind: 5, qind: 12},
    '2017-08-23': {row: 11, artind: 3, qind: 0},
    '2017-08-24': {row: 45, artind: 25, qind: 43},
    '2017-08-25': {row: 13, artind: 0, qind: 27},
    '2017-08-26': {row: 2, artind: 2, qind: 2},
    '2017-08-27': {row: 1, artind: 12, qind: 27},
    '2017-08-28': {row: 19, artind: 0, qind: 0},
    '2017-08-29': {row: 11, artind: 25, qind: 7}
  },
  {
    '2017-08-24': {row: 1, artind: 34, qind: 8},
    '2017-08-25': {row: 0, artind: 5, qind: 3},
    '2017-08-26': {row: 7, artind: 22, qind: 0}
  },
  {
    '2017-08-22': {row: 55, artind: 5, qind: 2},
    '2017-08-23': {row: 13, artind: 25, qind: 0},
    '2017-08-24': {row: 1, artind: 0, qind: 0},
    '2017-08-25': {row: 6, artind: 8, qind: 0},
    '2017-08-26': {row: 0, artind: 12, qind: 89},
    '2017-08-27': {row: 11, artind: 29, qind: 5}
  }
];

var dataout = { };

for(set=0; set<datain.length; set++)
{
    for(date in datain[set])
    {
        for(field in datain[set][date])
        {
            if ( typeof dataout[date] === 'undefined' ) { dataout[date] = { }; }
            if ( typeof dataout[date][field] === 'undefined' ) { dataout[date][field] = 0; }
            dataout[date][field] += datain[set][date][field];
        }
    }
}
console.log(data out);

这为您提供了很小的结构灵活性,因此这取决于您的数据是否会发生变化。

答案 2 :(得分:0)

这是使用Lodash的解决方案,它与Underscore非常相似。您应该能够非常轻松地翻译呼叫(或者只使用Lodash,因为它更快更好;)

基本上你想要做的是展平嵌套对象,找到一种方法,你可以按日期分组,然后使用sumBy作为内部值。

如果以下任何代码不清楚,请与我们联系。

let items = [
    {
        '2017-08-21': {row: 0, artind: 25, qind: 20},
        '2017-08-22': {row: 1, artind: 5, qind: 12},
        '2017-08-23': {row: 11, artind: 3, qind: 0},
        '2017-08-24': {row: 45, artind: 25, qind: 43},
        '2017-08-25': {row: 13, artind: 0, qind: 27},
        '2017-08-26': {row: 2, artind: 2, qind: 2},
        '2017-08-27': {row: 1, artind: 12, qind: 27},
        '2017-08-28': {row: 19, artind: 0, qind: 0},
        '2017-08-29': {row: 11, artind: 25, qind: 7}
    },
    {
        '2017-08-24': {row: 1, artind: 34, qind: 8},
        '2017-08-25': {row: 0, artind: 5, qind: 3},
        '2017-08-26': {row: 7, artind: 22, qind: 0}
    },
    {
        '2017-08-22': {row: 55, artind: 5, qind: 2},
        '2017-08-23': {row: 13, artind: 25, qind: 0},
        '2017-08-24': {row: 1, artind: 0, qind: 0},
        '2017-08-25': {row: 6, artind: 8, qind: 0},
        '2017-08-26': {row: 0, artind: 12, qind: 89},
        '2017-08-27': {row: 11, artind: 29, qind: 5}
    }
]

const groupedItems = _(items)
    // get the nested objects, break them out, and give them date and value keys that we can use later
    .map(item =>{
      const keys = Object.keys(item);
      return _.map(keys, key => {
        return {
          date: key, // i.e. date: 2017-08-22
          value: item[key] // i.e. value: {row: 1, artind: 5, qind: 12}
        }
      })
    })
    // flatten all the nested items into one array
    .flatten()
    // group by the date key we created earlier i.e. 2017-08-22 : [array with 2 entries]
    .groupBy(item => item.date)
    // take each of these dateItems, and internally sum their individual nested values, then return
    .map(dateItem => {
      const date = dateItem[0].date; // just grab the first date value, we'll use that as our final key
      const row = _.sumBy(dateItem, innerItem => innerItem.value.row);
      const artind = _.sumBy(dateItem, innerItem => innerItem.value.artind);
      const qind = _.sumBy(dateItem, innerItem => innerItem.value.qind);
      const returnObject = {
        [date]: {row, artind, qind}
      };
      return(returnObject);
    })
    // call valueOf to execute the chain
    .valueOf();


    console.log(groupedItems);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

答案 3 :(得分:0)

我要添加到您的答案列表中。只有这个片段添加了默认值以防止未定义。

var arr = [
    {
        '2017-08-21': { artind: 25, qind: 20 },
        '2017-08-22': { row: 1, artind: 5, qind: 12 },
        '2017-08-23': { row: 11, artind: 3, qind: 0 },
        '2017-08-24': { row: 45, artind: 25, qind: 43 },
        '2017-08-25': { row: 13, artind: 0, qind: 27 },
        '2017-08-26': { row: 2, artind: 2, qind: 2 },
        '2017-08-27': { row: 1 },
        '2017-08-28': { row: 19, artind: 0, qind: 0 },
        '2017-08-29': { row: 11, artind: 25, qind: 7 }
    },
    {
        '2017-08-24': { row: 1, artind: 34, qind: 8 },
        '2017-08-25': { row: 0, artind: 5, qind: 3 },
        '2017-08-26': { row: 7, artind: 22, qind: 0 }
    },
    {
        '2017-08-22': { artind: 5, qind: 2 },
        '2017-08-23': { row: 13, artind: 25, qind: 0 },
        '2017-08-24': { row: 1},
        '2017-08-25': { row: 6, artind: 8, qind: 0 },
        '2017-08-26': { row: 0, artind: 12, qind: 89 },
        '2017-08-27': { row: 11, artind: 29, qind: 5 }
    }
];
var acc = _.reduce(arr, function (acc, elem) {
            _.each(elem, function (value, key) {
                _.defaults(value, {row: 0, artind:0 , qind: 0});
                if (_.has(acc, key)) {
                    acc[key].row += value.row;
                    acc[key].artind += value.artind;
                    acc[key].qind += value.qind;
                }
                else {
                    acc[key] = value;
                }
            });
            return acc;
          }, {});
console.log(acc);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>