У меня есть следующий массив:
var objArray = [
{ num: 1, date: '1/12/2017' },
{ num: 3, date: '1/12/2017' },
{ num: 7, date: '1/12/2017' },
{ num: 1, date: '1/13/2018' },
{ num: 3, date: '1/16/2018' },
{ num: 4, date: '1/16/2018' }
];
Я хочу объединить их с одинаковыми датами, чтобы выходной массив выглядел так:
var outputArr = [
{ num: 11, date: '1/12/2017' },
{ num: 1, date: '1/13/2018' },
{ num: 7, date: '1/16/2018' }
];
Я добавляю все num
с похожими датами и создаю один новый объект.
У меня есть очень большой набор данных объектов, таких как этот, поэтому я пытаюсь уменьшить количество времени на обработку для этого.
Я отсортировал массивы по дате, чтобы они отражали objArray
.
Циклы for кажутся громоздкими, поскольку я беру первую дату в массиве и проверяю каждый второй элемент массива в виде следующего псевдокода:
var newArr = [];
for(i = 0; i < objArray.length; i++) {
for(j = 0; j < objArray.length; j++) {
var tempArr = [];
// check every date manually
// add similar to new array
tempArr.push({ similar items });
}
newArr.push(tempArr):
}
// Do another couple loops to combine those like arrays into another array
Должен быть более элегантный способ сделать это, чем запуск нескольких циклов for.
Мы ценим любые предложения.
4 ответа
Просто используйте Array.reduce()
для создания карты и группировки значений по дате, Object.values()
на карте даст вам желаемое выходное значение:
let arr = [ { num: 1, date: '1/12/2017' }, { num: 3, date: '1/12/2017' }, { num: 7, date: '1/12/2017' }, { num: 1, date: '1/13/2018' }, { num: 3, date: '1/16/2018' }, { num: 4, date: '1/16/2018' } ];
let result = Object.values(arr.reduce((a, {num, date})=>{
if(!a[date])
a[date] = Object.assign({},{num, date});
else
a[date].num += num;
return a;
},{}));
console.log(result);
Вы также можете удалить операторы if и использовать Set, если хотите быть еще более декларативным.
var objArray = [
{ num: 1, date: '1/12/2017' },
{ num: 3, date: '1/12/2017' },
{ num: 7, date: '1/12/2017' },
{ num: 1, date: '1/13/2018' },
{ num: 3, date: '1/16/2018' },
{ num: 4, date: '1/16/2018' }
];
var mSet = new Set(objArray.map(d => d.date));
return Array.from(mSet).map(d => {
return
{
date: d,
sum: (objArray
.filter(o => o.date === d)
.map(n => n.num)
.reduce((a, c) => a + c, 0))
}
);
Это возвращает:
[{ date: 1/12/2017, sum: 11},
{ date: 1/13/2018, sum: 1 },
{ date: 1/16/2018, sum: 7 }]
Используя lodash,
// Aggregate num from unique dates
var g = _.groupBy(objArray,'date')
Object.keys(g).map(k=>({num:g[k].reduce((a,c)=>c.num+a,0),date:k}))
var objArray = [
{ num: 1, date: '1/12/2017' },
{ num: 3, date: '1/12/2017' },
{ num: 7, date: '1/12/2017' },
{ num: 1, date: '1/13/2018' },
{ num: 3, date: '1/16/2018' },
{ num: 4, date: '1/16/2018' }
];
let outputArr = Array.from(objArray.reduce((acc, obj)=>{
acc.set(obj.date, (acc.get([obj.date]) || 0) + obj.num);
return acc;
}, new Map()))
.map(kv=>({num: kv[1], date: kv[0]}))
console.log(outputArr);
Дает:
[ { num: 11, date: '1/12/2017' },
{ num: 1, date: '1/13/2018' },
{ num: 7, date: '1/16/2018' } ]
Похожие вопросы
Новые вопросы
javascript
Для вопросов, касающихся программирования в ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (исключая ActionScript). Этот тег редко используется отдельно, но чаще всего ассоциируется с тегами [node.js], [jquery], [json] и [html].