合并不同长度的对象
Merging objects of different lengths
我有一个对象数组,以日期字符串为键,布局如下:
[
{
'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}
}
]
我需要对每个对象中的所有值求和。所以最后,我需要一个看起来像这样的对象:
{
'2017-08-21': {row: 0, artind: 25, qind: 20},
'2017-08-22': {row: 56, artind: 10, qind: 14},
'2017-08-23': {row: 24, artind: 28, qind: 0},
'2017-08-24': {row: 47, artind: 59, qind: 51},
'2017-08-25': {row: 19, artind: 13, qind: 30},
'2017-08-26': {row: 9, artind: 36, qind: 91},
'2017-08-27': {row: 12, artind: 41, qind: 32},
'2017-08-28': {row: 19, artind: 0, qind: 0},
'2017-08-29': {row: 11, artind: 25, qind: 7}
}
我真正用于支持的唯一库是 underscore.js,所以非常感谢这些答案!
谢谢
您可以使用以下reduce方法来解决您的问题。
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;
}, {});
编辑:只是格式化
我不确定这是最好的方法,但我会这样做。
假设变量 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);
这给您带来的结构灵活性很小,因此这实际上取决于您的数据是否会发生变化。
这里有一个使用 Lodash 的解决方案,它与 Underscore 非常相似。您应该能够非常轻松地翻译调用(或者只使用 Lodash,因为它更快更好;))
基本上您要做的是展平嵌套对象,找到一种可以按日期分组的方法,然后对内部值求和。
如果下面的任何代码不清楚,请告诉我。
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>
我将添加到您的答案列表中。只有这个片段添加了默认值以防止未定义。
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>
.
我有一个对象数组,以日期字符串为键,布局如下:
[
{
'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}
}
]
我需要对每个对象中的所有值求和。所以最后,我需要一个看起来像这样的对象:
{
'2017-08-21': {row: 0, artind: 25, qind: 20},
'2017-08-22': {row: 56, artind: 10, qind: 14},
'2017-08-23': {row: 24, artind: 28, qind: 0},
'2017-08-24': {row: 47, artind: 59, qind: 51},
'2017-08-25': {row: 19, artind: 13, qind: 30},
'2017-08-26': {row: 9, artind: 36, qind: 91},
'2017-08-27': {row: 12, artind: 41, qind: 32},
'2017-08-28': {row: 19, artind: 0, qind: 0},
'2017-08-29': {row: 11, artind: 25, qind: 7}
}
我真正用于支持的唯一库是 underscore.js,所以非常感谢这些答案!
谢谢
您可以使用以下reduce方法来解决您的问题。
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;
}, {});
编辑:只是格式化
我不确定这是最好的方法,但我会这样做。
假设变量 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);
这给您带来的结构灵活性很小,因此这实际上取决于您的数据是否会发生变化。
这里有一个使用 Lodash 的解决方案,它与 Underscore 非常相似。您应该能够非常轻松地翻译调用(或者只使用 Lodash,因为它更快更好;))
基本上您要做的是展平嵌套对象,找到一种可以按日期分组的方法,然后对内部值求和。
如果下面的任何代码不清楚,请告诉我。
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>
我将添加到您的答案列表中。只有这个片段添加了默认值以防止未定义。
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>
.