Как сгруппировать и добавить их значение в массив объектов в JavaScript? - PullRequest
0 голосов
/ 19 января 2019

У меня есть этот ответ в моем угловом приложении. Я должен уменьшить код.

res=[
{  "url": "/page1", "views": 2 },
{  "url": "/page2", "views": 1 },
{  "url": "/page1", "views": 10 },
{  "url": "/page2", "views": 4 },
{  "url": "/page3", "views": 1 },
{  "url": "/page2", "views": 0 },
{  "url": "/page3", "views": 14 },
{  "url": "/page1", "views": 04 },
{  "url": "/page3", "views": 14 },
]

и мне нужен окончательный ответ, как

res=[
{  "url": "/page1", "views": 104 },
{  "url": "/page2", "views": 104 },
{  "url": "/page3", "views": 104 },
]

Ответы [ 3 ]

0 голосов
/ 19 января 2019

Использовать массив reduce()

var result = res.reduce((accu, obj) => {
       accu[obj.url] = (accu[obj.url] || 0) + obj.views;
       return accu;
    },
    {}
);

Выход из узла CLI:

> var result = res.reduce((accu, obj) => { accu[obj.url] = (accu[obj.url] || 0) + obj.views; return accu; }, {});
undefined
> result
{ '/page1': 16, '/page2': 5, '/page3': 29 }
0 голосов
/ 19 января 2019

Принятый ответ возвращает объект. Вы можете сделать что-то подобное, используя reduce, чтобы получить желаемый результат:

const res=[{"url":"/page1","views":2},{"url":"/page2","views":1},{"url":"/page1","views":10},{"url":"/page2","views":4},{"url":"/page3","views":1},{"url":"/page2","views":0},{"url":"/page3","views":14},{"url":"/page1","views":04},{"url":"/page3","views":14}],

merged = res.reduce((acc,{url,views})=> {
    acc[url] = acc[url] || {url, views:0}
    acc[url].views += views;
    return acc;
}, {}),

output = Object.values(merged)
console.log(output)

Вот более короткая версия приведенного выше кода:

const res=[{"url":"/page1","views":2},{"url":"/page2","views":1},{"url":"/page1","views":10},{"url":"/page2","views":4},{"url":"/page3","views":1},{"url":"/page2","views":0},{"url":"/page3","views":14},{"url":"/page1","views":04},{"url":"/page3","views":14}],

output = res.reduce((acc,{url,views})=>
    ((acc[url] = acc[url] || {url, views:0})["views"] += views, acc), {})
console.log(Object.values(output))

Другой вариант с использованием Map

const res=[{"url":"/page1","views":2},{"url":"/page2","views":1},{"url":"/page1","views":10},{"url":"/page2","views":4},{"url":"/page3","views":1},{"url":"/page2","views":0},{"url":"/page3","views":14},{"url":"/page1","views":04},{"url":"/page3","views":14}],

map = res.reduce((m,{url,views})=> {
    const o = m.get(url) || {url,views:0};
    o.views += views;
    return m.set(url, o);
}, new Map),

output = [...map.values()];
console.log(output)
0 голосов
/ 19 января 2019

Вы можете использовать простую reduce операцию:

 

var res = [
{  "url": "/page1", "views": 2 },
{  "url": "/page2", "views": 1 },
{  "url": "/page1", "views": 10 },
{  "url": "/page2", "views": 4 },
{  "url": "/page3", "views": 1 },
{  "url": "/page2", "views": 0 },
{  "url": "/page3", "views": 14 },
{  "url": "/page1", "views": 04 },
{  "url": "/page3", "views": 14 },
];

res = res.reduce((val, acc) => {
if (acc.some(e => e.url == val.url)) {
    acc.find(e => e.url == val.url).views += val.views;
} else {
    acc.push({
        url: val.url,
        views: val.views,
    });
}
return acc;
}, []);

console.log(res);
...