2015-02-06 3 views
0

[Обновить]: Я удалил большую часть макета и lodash (неудачный код) из ранее, потому что формат данных JSON изменился.lodash группировка массива с помощью нескольких ключей

Я пытаюсь сгруппировать набор данных для подготовки к агрегации итогов. Вот входящий макет JSON. Мне нужно сгруппировать по стране, а затем по бренду:

[ 
    { 
     $id: "1", 
     countryCode: "HT", 
     brand: "CO", 
     roomNights: 12, 
     hotelSpend: 2000 
    }, 
    { 
    $id: "2", 
    countryCode: "PK", 
    brand: "HH", 
    roomNights: 201, 
    hotelSpend: 10000 
    }, 
    { 
    $id: "3", 
    countryCode: "RO", 
    brand: "CO", 
    roomNights: 34, 
    hotelSpend: 5000 
    }, 
    { 
    $id: "4", 
    countryCode: "US", 
    brand: "ES", 
    roomNights: 120, 
    hotelSpend: 56000 
    }, 
    { 
    $id: "5", 
    countryCode: "PK", 
    brand: "HH", 
    roomNights: 145, 
    hotelSpend: 33000 
    } 
    ] 

потребности данные должны быть преобразованы в этот формат:

 ['Brand','HT'  , 'PK'  , 'US'  , 'RO', 'Avg Rm', 'Avg Spend'] 
     ['HH' ,'0/0' ,'201/10000', '0/0'  , '0/0'  , 201, 10000], 
     ['CO' ,'12/2000','0/0',  , '0/0'  , '34/5000', 23 , 3500], 
     ['ES' , '0/0' ,'0/0' , '120/50000' , '0/0' , 120, 50000] 

В roomNights и hotelSpend будут суммироваться за бренд & страны и в среднем в конце каждого из них должны быть вычисленные поля.

Спасибо!

+0

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

+0

Возможно, я могу сделать это в чистом js, но я думаю, это не то, что вы ищете – taesu

+0

Я открыт для этого. Что бы ни было легче :-) @taesu –

ответ

2

Давайте сначала определим mean функцию и добавить его в _:

_.mixin({ 
    mean: function(ds) { 
    return _(ds).foldr(function(a, b) { return a + b; }, 0)/ds.length; 
    } 
}); 

Определим функции для выбора строк и столбцов:

var row = function(d) { return d.brand; }; 
var col = function(d) { return d.countryCode; }; 

aggr функция принимает суб-список наших данных и объединяет его значения в одно значение (которое представляет собой строковое представление рационального числа):

var aggr = function(ds) { 
    var val = _(ds).foldr(function(a, b) { 
    return { 
     roomNights: a.roomNights + b.roomNights, 
     hotelSpend: a.hotelSpend + b.hotelSpend 
    }; 
    }, {roomNights: 0, hotelSpend: 0}); 

    return val.roomNights + "/" + val.hotelSpend; 
}; 

Наши строки и столбцы метки:

rows = _.chain(data).map(row).unique().value(); 
columns = _.chain(data).map(col).unique().value(); 

Стержень:

[["Brand/Country"].concat(columns).concat(["Avg Rm", "Avg Spend"])] // header row 
.concat(_(rows).map(function(r){ 

    // data in this row 
    rdata = _(data).filter(function(d) { return row(d) == r; }); 

    return [r].concat(_(columns).map(function(c){ 
    return aggr(_(rdata).filter(function(d) {return col(d) == c; })); 
    })) 
    // the last two columns in each row 
    .concat([ 
    _.chain(rdata).map(function(d) { return d.roomNights; }).mean().value(), 
    _.chain(rdata).map(function(d) { return d.hotelSpend; }).mean().value() 
    ]); 
})); 

Вы можете контролировать порядок или отфильтровать результаты по конкретному countryCode или brand путем изменения rows и columns массивы, подобные к электронным таблицам.

+0

Спасибо @homam! –

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