如何使用类似的键对数据进行分组?

时间:2016-05-19 13:57:59

标签: javascript arrays json

我有来自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? 
            }
        }
    }
}

如果匹配,我创建了一个数组,其中我按下状态和计数。

但我真的不知道如何从那里开始。

感谢您的帮助!

4 个答案:

答案 0 :(得分: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的值为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
            }
        }
    }
}

综述:reduce返回一些高度可控的内容。

答案 1 :(得分: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数据是数据变量

答案 2 :(得分:0)

使用reduce可以轻松完成:

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/

答案 3 :(得分: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>");
&#13;
&#13;
&#13;