[{
"_id": {
"year": 2017,
"month": 4
},
"Confirm": 0
}, {
"_id": {
"year": 2017,
"month": 4
},
"Expired": 25
}, {
"_id": {
"year": 2017,
"month": 4
},
"Pending": 390
}, {
"_id": {
"year": 2017,
"month": 5
},
"Pending": 1400
}]
上面的数组包含相同的月份和年份值。从MongoDB Aggregate生成。我想将它们合并到一个对象中,并保留它们拥有的任何键和值。
预期产出:
[{
month: 4,
year: 2017,
Expired: 25,
Pending: 390
}, {
month: 5,
year: 2017,
Pending: 1400
}]
我更喜欢最快的执行实现。欢迎Underscorejs或本地人。感谢
答案 0 :(得分:1)
这需要一点点分开,但它是线性的:
const ary = [{
"_id": {
"year": 2017,
"month": 4
},
"Confirm": 0
}, {
"_id": {
"year": 2017,
"month": 4
},
"Expired": 25
}, {
"_id": {
"year": 2017,
"month": 4
},
"Pending": 390
}, {
"_id": {
"year": 2017,
"month": 5
},
"Pending": 1400
}];
const result = Object.values(ary.reduce((acc, cur) => {
const { month, year } = cur._id;
const key = `${month}-${year}`;
const obj = Object.assign({}, cur);
delete obj._id;
acc[key] = Object.assign(acc[key] || { month, year }, obj);
return acc;
}, {}));
console.log(result);
答案 1 :(得分:0)
这在O(N * logN)中进行排序,O(N)用于合并json。 希望这对你有用!
var obj = [{
_id: {
year: 2017,
month: 5,
},
Pending: 1400,
}, {
_id: {
year: 2017,
month: 4,
},
Expired: 25,
}, {
_id: {
year: 2017,
month: 4,
},
Pending: 390,
}, {
_id: {
year: 2017,
month: 4,
},
Confirm: 0,
}];
function compare(a, b) {
return a._id.year !== b._id.year
? a._id.year - b._id.year
: a._id.month - b._id.month;
}
var sorted = obj.sort(compare);
function join(a, b) {
return {
_id: a._id,
Pending: (a.Pending? a.Pending : 0) + (b.Pending? b.Pending : 0),
Confirm: (a.Confirm? a.Confirm : 0) + (b.Confirm? b.Confirm : 0),
Expired: (a.Expired? a.Expired : 0) + (b.Expired? b.Expired : 0),
};
}
var compressed = sorted.filter(function (value, index) {
if (!sorted[index + 1]) {
return true;
}
if (compare(value, sorted[index + 1]) === 0) {
sorted[index + 1] = join(value, sorted[index + 1]);
return false;
}
return true;
});
console.log(compressed);
// if you want month and year formatted:
console.log(compressed.map(function (o) {
const result = {
month: o._id.month,
year: o._id.year,
};
if (o.Pending !== undefined) result.Pending = o.Pending;
if (o.Confirm !== undefined) result.Confirm = o.Confirm;
if (o.Expired !== undefined) result.Expired = o.Expired;
return result;
}));

答案 2 :(得分:0)
您可以使用Map
进行分组,然后使用Array.from
来提取最终对象:
function merge(data) {
return Array.from(data.reduce( (acc, o) => {
const k = o._id.year * 100 + o._id.month;
const v = acc.get(k) || Object.assign({}, o._id);
for (let prop in o) {
if (prop !== '_id') v[prop] = o[prop];
}
return acc.set(k, v);
}, new Map), ([k, v]) => v);
}
// Sample data
const data = [{
"_id": {
"year": 2017,
"month": 4
},
"Confirm": 0
}, {
"_id": {
"year": 2017,
"month": 4
},
"Expired": 25
}, {
"_id": {
"year": 2017,
"month": 4
},
"Pending": 390
}, {
"_id": {
"year": 2017,
"month": 5
},
"Pending": 1400
}];
const result = merge(data);
console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }