2013-12-05 5 views
1

Я кодирую приложение, которое извлекает некоторые данные с рекламных платформ. Моя структура данных выглядит следующим образом:Каков наилучший способ манипулирования данными в NodeJS?

{ 
    campaign_id: 123, 
    campaign_name: SomeName, 
    subcampaigns: [ 
    {country: Australia, impressions: 12000, cost: 12}, 
    {country: Australia, impressions: 14000, cost: 17}, 
    {country: Singapore, impressions: 10000, cost: 7}, 
    {country: Singapore, impressions: 7000, cost: 6} 
    ] 
} 

мне нужно, чтобы превратить это в нечто вроде:

[{ 
    campaign_name: SomeName, 
    country: Australia, 
    impressions: 36000 
    cost: 29 
}, 
{ 
    campaign_name: SomeName, 
    country: Singapore 
    impressions: 17000 
    cost: 13 
}] 

Что бы быть лучшим способом сделать такие Map-Reduce операции в NodeJS?

Спасибо.

ответ

3

Один из возможных подходов:

var groupedSubcampaigns = _.groupBy(data.subcampaigns, 'country'); 
var summator = function(memo, el) { 
    return memo + el; 
}; 
var result = _.map(groupedSubcampaigns, function(group, country) { 
    return { 
     campaign_name: data.campaign_name, 
     country: country, 
     impressions: _.reduce(_.pluck(group, 'impressions'), summator, 0), 
     cost: _.reduce(_.pluck(group, 'cost'), summator, 0) 
    } 
}); 
console.log(result); 

Demo (как-то трудно найти Node.js онлайн codepad с возможностью включения внешних библиотек, но я думаю, jsfiddle будет работать нормально в данном случае).

Пояснение ... ну, я на самом деле считаю, что код довольно объясняющий здесь.) Сначала мы создаем хэш субкомпаний, сгруппированных по странам, затем мы просматриваем каждый элемент этого хэша с _.map, уменьшая его свойства impressions и cost с помощью функции «summator».

Там еще комната для улучшения, хотя вы можете оставить метод pluck и пройти через коллекцию с одним уменьшить, например:

var summator = function(memo, el) { 
    memo.impressions += el.impressions; 
    memo.cost += el.cost; 
    return memo; 
}; 
var result = _.map(groupedSubcampaigns, function(group, country) { 
    var aggregateObj = _.reduce(group, summator, {impressions:0, cost:0}); 
    return _.extend(aggregateObj, { 
     campaign_name: data.campaign_name, 
     country: country 
    }); 
}); 

Demo.

+0

Спасибо человек. Что произойдет, если мне нужно GroupBy несколько «полей»? – tounano

+0

Не могли бы вы привести пример? На первый взгляд, похоже, что в этом случае можно использовать составной ключ. – raina77ow

+0

Предположим, у меня есть в объекте "subcampaigns" banner_id. И конечный результат, который я ожидаю, должен быть: campaign_name | banner_id | country | impressions | стоимость – tounano

Смежные вопросы