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