JSON数据的JavaScript SUM和GROUP BY

vh0rcniy  于 2023-04-19  发布在  Java
关注(0)|答案(5)|浏览(245)

这是我第一次尝试使用JSON数据对象来编写JavaScript,我需要一些关于如何正确实现目标的建议。
一些服务器端代码实际上生成了一个JSON格式的字符串,我必须使用它并将其分配给一个字符串:

var dataString='$DATASTRING$';

但是在服务器替换它的数据之后,我必须处理的最终结果(当然没有\r\n):

var dataString='[ 
 { "category" : "Search Engines", "hits" : 5, "bytes" : 50189 },
 { "category" : "Content Server", "hits" : 1, "bytes" : 17308 },
 { "category" : "Content Server", "hits" : 1, "bytes" : 47412 },
 { "category" : "Search Engines", "hits" : 1, "bytes" : 7601 },
 { "category" : "Business", "hits" : 1, "bytes" : 2847 },
 { "category" : "Content Server", "hits" : 1, "bytes" : 24210 },
 { "category" : "Internet Services", "hits" : 1, "bytes" : 3690 },
 { "category" : "Search Engines", "hits" : 6, "bytes" : 613036 },
 { "category" : "Search Engines", "hits" : 1, "bytes" : 2858 } 
]';

然后我可以把它变成一个可以使用的对象。

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)已经包含在客户端页面中,但如果需要的话,我可以添加Underscore、jQuery或其他一些小库。
我只是不知道什么是最好的,最简单的,用最少的代码来处理查询。
有什么建议吗?

dauxcl2d

dauxcl2d1#

您可以使用本机函数.reduce()聚合数据,然后使用.sort()bytes排序。

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; });

如果您支持较旧的实现,则需要为.reduce()使用shim。

0ejtzxu1

0ejtzxu12#

如果你走LINQ.js路线,你可以这样做:

var aggregatedObject = Enumerable.From(dataArray)
    .GroupBy("$.category", null, function (key, g) {
        return {
          category: key,
          hits: g.Sum("$.hits"),
          bytes: g.Sum("$.bytes")
        }
    })
    .ToArray();

使用Stack Snippets进行演示:

var dataArray = [ 
  { category: "Search Engines", hits: 5, bytes: 50189 },
  { category: "Content Server", hits: 1, bytes: 17308 },
  { category: "Content Server", hits: 1, bytes: 47412 },
  { category: "Search Engines", hits: 1, bytes: 7601  },
  { category: "Business",       hits: 1, bytes: 2847  },
  { category: "Content Server", hits: 1, bytes: 24210 },
  { category: "Internet ",      hits: 1, bytes: 3690  },
  { category: "Search Engines", hits: 6, bytes: 613036 },
  { category: "Search Engines", hits: 1, bytes: 2858  } 
];

var aggregatedObject = Enumerable.From(dataArray)
    .GroupBy("$.category", null, function (key, g) {
        return {
          category: key,
          hits: g.Sum("$.hits"),
          bytes: g.Sum("$.bytes")
        }
    })
    .ToArray();

console.log(aggregatedObject);
<script src="//cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.min.js"></script>

进一步阅读linqjs group by with a sum

bq3bfh9z

bq3bfh9z3#

给定上面的dataString,下面的代码似乎可以工作。如果类别存在于groupedObjects数组中,则其命中和字节被添加到现有对象。否则,它被认为是新的并被添加到groupedObjects数组。
此解决方案使用了underscore.js和jQuery
下面是一个jsfiddle演示:http://jsfiddle.net/R3p4c/2/

var objects = $.parseJSON(dataString);
var categories = new Array();
var groupedObjects = new Array();
var i = 0;

_.each(objects,function(obj){
    var existingObj;
    if($.inArray(obj.category,categories) >= 0) {
        existingObj = _.find(objects,function(o){return o.category === obj.category; });
        existingObj.hits += obj.hits;
        existingObj.bytes += obj.bytes;
    } else {
        groupedObjects[i] = obj;
        categories[i] = obj.category;
        i++;
  }
});

groupedObjects = _.sortBy(groupedObjects,function(obj){ return obj.bytes; }).reverse();
x4shl7ld

x4shl7ld4#

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}]"
z5btuh9x

z5btuh9x5#

嗨,这里是我写的一个解决方案访问:aggregate_groupby_js on npm或in
用于在对象数组上使用聚合函数的javascript库。基本函数,如SUM,MIN,MAX,AVG,DISTINCT_COUNT,用于整个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();

相关问题