JSON数据的JavaScript求和和和分组方式

JSON数据的JavaScript求和和和分组方式,javascript,json,group-by,sum,Javascript,Json,Group By,Sum,这是我第一次尝试使用一些JSON数据对象编写JavaScript,需要一些关于实现目标的正确方法的建议 一些服务器端代码实际上生成了一个JSON格式的字符串,我必须使用该字符串并将其分配给一个字符串: var dataString='$DATASTRING$'; 但是,在服务器替换其数据后(当然没有\r\n),我必须处理的最终结果是: 然后我可以把它变成一个要处理的对象 var dataObject=eval("("+dataString+")"); 这允许我访问数据的各个行,但我需要对值进

这是我第一次尝试使用一些JSON数据对象编写JavaScript,需要一些关于实现目标的正确方法的建议

一些服务器端代码实际上生成了一个JSON格式的字符串,我必须使用该字符串并将其分配给一个字符串:

var dataString='$DATASTRING$';
但是,在服务器替换其数据后(当然没有\r\n),我必须处理的最终结果是:

然后我可以把它变成一个要处理的对象

var dataObject=eval("("+dataString+")");
这允许我访问数据的各个行,但我需要对值进行求和、分组和排序

我需要一个SQL语句的等价物,如下所示:

SELECT category, sum(hits), sum(bytes) 
FROM dataObject
GROUP BY category
ORDER BY sum(bytes) DESC
我想要的输出是这样一个对象,我可以进一步处理:

var aggregatedObject='[ 
 { "category" : "Search Engines", "hits" : 13, "bytes" : 673684 },
 { "category" : "Content Server", "hits" : 3, "bytes" : 88930 },
 { "category" : "Internet Services", "hits" : 1, "bytes" : 3690 },
 { "category" : "Business", "hits" : 1, "bytes" : 2847 } 
]';
…但我不知道从哪里开始

我可以循环遍历所有的类别值,首先找到唯一的类别,然后再次循环并对点击数和字节数求和,然后再次排序,但似乎有一种更简单的方法

prototype.js(1.7)已经包含在客户端页面上,但是如果有必要,我可以添加下划线、jQuery或其他一些小库

我只是不知道用最少的代码来处理查询,什么是最好的、最简单的、最小的


有什么建议吗?

鉴于上面的数据字符串,下面的代码似乎有效。它穿过每一个物体;如果类别存在于
groupedObjects
数组中,则其命中数和字节将添加到现有对象中。否则,它将被视为新的,并添加到GroupedObject数组中

此解决方案使用下划线.js和jQuery

下面是一个JSFIDLE演示:


您可以使用本机函数
.reduce()
对数据进行聚合,然后
.sort()
字节进行排序

var result = dataObject.reduce(function(res, obj) {
    if (!(obj.category in res))
        res.__array.push(res[obj.category] = obj);
    else {
        res[obj.category].hits += obj.hits;
        res[obj.category].bytes += obj.bytes;
    }
    return res;
}, {__array:[]}).__array
                .sort(function(a,b) { return b.bytes - a.bytes; });
如果您支持较旧的实现,则需要使用。

var obj=[{Poz:'F1',Cap:10},{Poz:'F1',Cap:5},{Poz:'F1',Cap:5},{Poz:'F2',Cap:20},{Poz:'F1',Cap 5},{Poz:'F1',Cap 15},{Poz:'F2',Cap 5},{Poz:'F3',Cap 5},{Poz:'F4',Cap 5};
Array.prototype.sumUnic=函数(名称,sumName){
var returnArr=[];
var obj=这个;
对于(var x=0;x如果你走这条路线,你可以这样做:

SELECT category, sum(hits), sum(bytes) 
FROM dataObject
GROUP BY category
ORDER BY sum(bytes) DESC
var aggregatedObject=Enumerable.From(dataArray)
.GroupBy(“$.category”),空,
功能(键,g){
返回{
类别:重点,,
点击次数:g.Sum($点击次数),
字节:g.Sum($.bytes)
}
})
.ToArray();
使用堆栈片段进行演示:
var dataArray=[
{类别:“搜索引擎”,点击数:5,字节数:50189},
{类别:“Content Server”,点击数:1,字节数:17308},
{类别:“Content Server”,点击数:1,字节数:47412},
{类别:“搜索引擎”,点击数:1,字节数:7601},
{类别:“业务”,点击:1,字节:2847},
{类别:“Content Server”,点击数:1,字节数:24210},
{类别:“互联网”,点击数:1,字节数:3690},
{类别:“搜索引擎”,点击数:6,字节数:613036},
{类别:“搜索引擎”,点击数:1,字节:2858}
];
var aggregatedObject=Enumerable.From(数据数组)
.GroupBy(“$.category”),空,
功能(键,g){
返回{
类别:重点,,
点击次数:g.Sum($点击次数),
字节:g.Sum($.bytes)
}
})
.ToArray();
console.log(聚合对象);

嗨,这里是我写的一个解决方案,请访问: 或者

用于在对象数组上使用聚合函数的javascript库。基本函数(如SUM、MIN、MAX、AVG、DISTINCT_)用于整个javascript对象

例如:

var arr = [{`"shape"`:`"square"`,`"color"`:`"red"`,`"used"`:1,`"instances"`:1},
    {`"shape"`:`"square"`,`"color"`:`"red"`,`"used"`:2,`"instances"`:1},
    {`"shape"`:`"circle"`,`"color"`:`"blue"`,`"used"`:0,`"instances"`:0},
    {`"shape"`:`"square"`,`"color"`:`"blue"`,`"used"`:4,`"instances"`:4},
    {`"shape"`:`"circle"`,`"color"`:`"red"`,"`used"`:1,`"instances"`:1},
    {`"shape"`:`"circle"`,`"color"`:`"red"`,`"used"`:1,`"instances"`:0},
    {`"shape"`:`"square"`,`"color"`:`"blue"`,`"used"`:4,`"instances"`:5}, 
    {`"shape"`:`"square"`,`"color"`:`"red"`,`"used"`:2,`"instances"`:1}];

// Specify columns
    var columns =[`"used"`, `"instances"`];

// Initialize object
    var gb = new GroupBy(arr,columns);
// or
    var gb = new GroupBy(arr,[`"used"`, `"instances"`]);

// Call the aggregate functions    
    gb.sum();
    gb.min();
    gb.max();
    gb.avg();
    gb.distinctCount();

可能没有你所需要的一切,但可能对你有帮助。不错的开始寻找的地方,但仍然需要jQuery用于Agrgate函数。比我想要的多一点。可能会在我脑海中的另一个项目中派上用场。谢谢。做的正是我想要做的。我输入了我收到的实际完整数据集(1000多个数组元素)输入到JSFIDLE中,得到了正确的值。缺点是它需要下划线和jQuery。我希望减少必须包含的工作量。(无法热链接到外部,因为它可能在封闭的网络上)但总的来说,我喜欢我可能很快就会做的其他一些事情的灵活性。漂亮。完全符合我的要求,只需要一个小垫片来减少。(甚至在IE6中也有效:)我想这是我错过的关键,因为我看到了。reduce引用了它,但无法使它工作。它的开销似乎是最低的,并且完成了我所需要的。真棒。嗯。现在我想知道是否有一种简单的方法来绘制它?我只是想做一个文本表,但可能是一个字节或点击量的图表。有好的绘图例程吗?@LordChariot:Google可能会向您展示许多优秀的绘图库。请先尝试一下,然后在遇到问题时提问。
:)
WoW…我也在搜索这个…谢谢..1等待答案…)看来你的回调函数不是一个纯函数。它改变了原来的数组。所以我们不能重用初始数据来处理另一个步骤。顺便说一句,谢谢你的回答。
var obj = [{Poz:'F1',Cap:10},{Poz:'F1',Cap:5},{Poz:'F1',Cap:5},{Poz:'F2',Cap:20},{Poz:'F1',Cap:5},{Poz:'F1',Cap:15},{Poz:'F2',Cap:5},{Poz:'F3',Cap:5},{Poz:'F4',Cap:5},{Poz:'F1',Cap:5}];
Array.prototype.sumUnic = function(name, sumName){
    var returnArr = [];
    var obj = this;
    for(var x = 0; x<obj.length; x++){
        if((function(source){
            if(returnArr.length == 0){
                return true;
            }else{
                for(var y = 0; y<returnArr.length; y++){
                    var isThere = [];
                    if(returnArr[y][name] == source[name]){
                        returnArr[y][sumName] = parseInt(returnArr[y][sumName]) + parseInt(source[sumName]);
                        return false;
                    }else{
                        isThere.push(source);
                    }
                }
                if(isThere.length>0)returnArr.push(source);
                return false;
            }
        })(obj[x])){
            returnArr.push(obj[x]);
        }
    }
    return returnArr;
}
obj.sumUnic('Poz','Cap');
// return "[{"Poz":"F1","Cap":45},{"Poz":"F2","Cap":25},{"Poz":"F3","Cap":5},{"Poz":"F4","Cap":5}]"
var arr = [{`"shape"`:`"square"`,`"color"`:`"red"`,`"used"`:1,`"instances"`:1},
    {`"shape"`:`"square"`,`"color"`:`"red"`,`"used"`:2,`"instances"`:1},
    {`"shape"`:`"circle"`,`"color"`:`"blue"`,`"used"`:0,`"instances"`:0},
    {`"shape"`:`"square"`,`"color"`:`"blue"`,`"used"`:4,`"instances"`:4},
    {`"shape"`:`"circle"`,`"color"`:`"red"`,"`used"`:1,`"instances"`:1},
    {`"shape"`:`"circle"`,`"color"`:`"red"`,`"used"`:1,`"instances"`:0},
    {`"shape"`:`"square"`,`"color"`:`"blue"`,`"used"`:4,`"instances"`:5}, 
    {`"shape"`:`"square"`,`"color"`:`"red"`,`"used"`:2,`"instances"`:1}];

// Specify columns
    var columns =[`"used"`, `"instances"`];

// Initialize object
    var gb = new GroupBy(arr,columns);
// or
    var gb = new GroupBy(arr,[`"used"`, `"instances"`]);

// Call the aggregate functions    
    gb.sum();
    gb.min();
    gb.max();
    gb.avg();
    gb.distinctCount();