多个分组JSON对象

时间:2014-08-15 18:37:06

标签: javascript json grouping

我想从中获取一个新的JSON对象:

(group by "a" & group by "b" field with sum "d" and with count(objects))

var json = [
    {"a":121, "b":212, "c":"0", "d":100},
    {"a":121, "b":212, "c":"0", "d":300},
    {"a":121, "b":210, "c":"0", "d":200},
    {"a":120, "b":210, "c":"0", "d":300}
    ];

var new_json = [
    {"a":121, "b":212, "c":"0", "d":400, "count":2},
    {"a":121, "b":210, "c":"0", "d":200, "count":1},
    {"a":120, "b":210, "c":"0", "d":300, "count":1}
    ];

没有下划线js有可能吗?你能救我吗?

3 个答案:

答案 0 :(得分:1)

根据OP,请找到 fiddle

var json = [
    {"a":121, "b":212, "c":"0", "d":100},
    {"a":121, "b":212, "c":"0", "d":300},
    {"a":121, "b":210, "c":"0", "d":200},
    {"a":120, "b":210, "c":"0", "d":300}
];

function compare(first, second) {
  if (first.a < second.a && first.b < second.b)
     return -1;
  if (first.a > second.a && first.b > second.b)
     return 1;
  return 0;
}


var sorted = json.sort(compare);
var length = sorted.length;
for (var i = 0; i < length; i+=1) {
    sorted[i].count = 1;
}

for (var i = 0; i < sorted.length-1; i+=1) {
    for(var j = i+1; j < sorted.length; j += 1) {
        if(sorted[i].a === sorted[j].a) {
            sorted[i].count += 1;
            sorted[i].d += sorted[j].d;
            sorted.splice(j, 1);
        }
    }
}

console.log(JSON.stringify(sorted, ' ', 2));

输出:

[
  {
    "a": 121,
    "b": 212,
    "c": "0",
    "d": 400,
    "count": 2
  },
  {
    "a": 121,
    "b": 210,
    "c": "0",
    "d": 200,
    "count": 1
  },
  {
    "a": 120,
    "b": 210,
    "c": "0",
    "d": 300,
    "count": 1
  }
] 

答案 1 :(得分:0)

此版本使用Array.prototype.forEach使用复合键创建或更新tmp对象中的条目来迭代所有条目:entry.a + ":" + entry.b

完成后,它会将生成的键数组映射到值数组中并返回结果。

代码:

var json = [
    {"a":121, "b":212, "c":"0", "d":100},
    {"a":121, "b":212, "c":"0", "d":300},
    {"a":121, "b":210, "c":"0", "d":200},
    {"a":120, "b":210, "c":"0", "d":300}
    ];

function calcSums(entries) {    
    var result = {};
    entries.forEach(function(val) {
        // Generate a key using val.a and val.b
        var key = val.a + ":" + val.b;

        // If an entry doesn't exist for the key, initialize a new one, otherwise
        // use the existing entry
        result[key] = result[key] || { a: val.a, b: val.b, c: val.c, d: 0, count: 0 };

        result[key].d += val.d;
        result[key].count++;
    });

    // Map an array of keys into an array of values    
    return Object.keys(result).map(function(key) {
        return(result[key]);
    });
}

console.log(JSON.stringify(calcSums(json), null, 2));

结果:

[
  {
    "a": 121,
    "b": 212,
    "c": "0",
    "d": 400,
    "count": 2
  },
  {
    "a": 121,
    "b": 210,
    "c": "0",
    "d": 200,
    "count": 1
  },
  {
    "a": 120,
    "b": 210,
    "c": "0",
    "d": 300,
    "count": 1
  }
]

demo fiddle

答案 2 :(得分:0)

您可以使用Alasql库来完成此操作。

var res = alasql('SELECT a,b,c,SUM(d) AS d,COUNT(*) AS [count] FROM ? \
                  GROUP BY a,b,c',[json]);

试试这个例子at jsFiddle

正式地说,这个例子不使用Underscore,但是我把它放在这里,因为你可以在一行中对多个列进行分组和求和。