2016-05-19 2 views
1

У меня есть эти данные из CSV:Как сгруппировать данные с помощью аналогичных ключей?

Group Profession Status   Count 
6  Fisherman Offer Accepted 1 
6  Fisherman All    1 
7  Fisherman Offer Accepted 1 
7  Fisherman All    1 
8  Banker  Onboard   2 
8  Banker  All    2 
8  Cook  Onboard   4 
8  Cook  All    4 
8  Developer Onboard   2 
8  Developer All    2 
9  Banker  Onboard   2 
9  Banker  Offer Accepted 1 
9  Banker  All    3 

Что мне нужно, чтобы вернуться как массив JSON:

"Fisherman" : { 
    6 : { 
     "Offer Accepted" : 1, 
     "All" : 1 
    }, 
    7 : { 
     "Offer Accepted" : 1, 
     "All" : 1 
    } 
}, 
"Banker" : { 
    8 : { 
     "Onboard" : 2, 
     "All" : 2 
    }, 
    9 : { 
     "Onboard" : 2, 
     "Offer Accepted" : 1, 
     "All" : 3 
    } 
}, 
....so on 

До сих пор, что я сделал, я получил все уникальные профессии и группы.

Затем я просмотрел все данные и сравнил их, если есть соответствие для профессии и группы.

for(var d in data) { 
    var json = []; 
    for(var p in profession) { 
     for(var g in group) { 
      if(data[d]["Profession"] == profession[p] && data[d]["Group"] == group[g]) { 
       json.push({data[d]["Status"] : data[d]["Count"]}); 
       // put 'json' variable in JSON array with key group? 
      } 
     } 
    } 
} 

Если есть совпадение, я создал массив, в котором я нажал состояние и количество.

Но я действительно не знаю, как исходить оттуда.

Благодарим за помощь!

+2

пожалуйста, добавьте данные, а также. –

+0

'json.push ({data [d] [" Status "]: data [d] [" Count "]})' недействителен JavaScript. –

ответ

2

Пусть данные представляют собой массив объектов, как,

{ Group: 6, Profession: 'Fisherman', Status: 'Offer Accepted', Count: 1 } 

то вы можете использовать следующее:

var order = ['Profession', 'Group', 'Status'], 
    object = {}; 

data.forEach(function (d) { 
    order.reduce(function (r, a) { 
     r[d[a]] = r[d[a]] || {}; 
     return r[d[a]]; 
    }, object).Count = d.Count; 
}); 

Как это работает:

d является объектом со структурой, как выше. oder - массив с ключами в нужном порядке для результата object. (Я переименовал json в object, потому что JSON является строка со специальным форматированием и не объект, как здесь необходимо.)

Для присвоения счета, необходимо знать путь к собственности. Это предоставляется с итерацией по order для ключей реального объекта d.

r[d[a]] = r[d[a]] || {}; 

Этого d[a] берется для проверки, если выезды собственности и если не присвоить пустой объект.

В конце обратного вызова возвращается ссылка на последний объект r[d[a]].

наконец, новое свойство Count является assinged со значением d.Count

object      a   d[a]   return value 
---------------------------- ---------- -------------- ------------ 
{}       Profession Fisherman  {} 
       /--------------------------------------/   (same reference) 
{ "Fisherman": {} }   Group  6    {} 
         /-------------------------------/   (same reference) 
{ "Fisherman": { "6": {} } } Status  Offer Accepted {} 

объекта после первого цикла данных

{ 
    "Fisherman": { 
     "6": { 
      "Offer Accepted": { 
       "Count": 1 
      } 
     } 
    } 
} 

Roundup: reduce возвращает что-то, что высоко контролируемый.

+0

Это сделало это. Это первый раз, когда я буду использовать 'reduce'. Не могли бы вы подробнее объяснить свой код? Особенно эта часть 'return r [d [a]]; }, json) .Count = d.Count; 'Спасибо! – user1526570

0

Попробуйте это:

var result = new Array(); 
for(var d in data){ 
    if(result[d.profession] == 'undefined'){ 
     result[d.profession] = new Array(); 
    } 
    if(result[d.profession][d.group] == 'undefined'){ 
     result[d.profession][d.group] = new Array(); 
    } 
    result[d.profession][d.group][d.status] = d.count; 
} 

result = JSON.stringify(result);//convert array to json 
console.log(result); 

Я не проверял это, и я должен ваши данные в формате JSON в переменной данных

0

Вы можете сделать это довольно легко с уменьшить:

const result = data.reduce((result, row) => { 
    ensureKeyExists(result, row.Profession); 
    ensureKeyExists(result[row.Profession], row.Group); 

    result[row.Profession][row.Group][row.Status] = row.Count; 

    return result; 
}, {}); 

function ensureKeyExists(object, key, defaultVal = {}) { 
    if (!object[key]) { 
    object[key] = defaultVal; 
    } 
} 

Полный пример: https://jsfiddle.net/k1zk3ses/

0

Если предположить, что ваши данные в этой форме, одно решение может быть получено с использованием Array.prototype.reduce() следующим образом;

var str = 'Group,Profession,Status,Count\n6,Fisherman,OfferAccepted,1\n6,Fisherman,All,1\n7,Fisherman,OfferAccepted,1\n7,Fisherman,All,1\n8,Banker,On Board,2\n8,Banker,All,2\n8,Cook,On Board,4\n8,Cook,All,4\n8,Developer,On Board,2\n8,Developer,All,2\n9,Banker,On Board,2\n9,Banker,OfferAccepted,1\n9,Banker,All,3', 
 
    data = str.split("\n").map(s => s.split(",")).slice(1), 
 
    jdata = data.reduce((p,c) => (p[c[1]] ? p[c[1]][c[0]] ? p[c[1]][c[0]][c[2]] = c[3] 
 
                 : p[c[1]][c[0]] = {[c[2]]:c[3]} 
 
             : p[c[1]] = {[c[0]]:{[c[2]]:c[3]}},p),{}); 
 

 
document.write("<pre>" + JSON.stringify(jdata,null,2) + "</pre>");

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