如何按每个id对数组中的对象求和,计算平均总和,按条件设置

How to sum objects in array by each id, count average sum, set in order with condition

我正在使用 mongoose find() 方法从数据库中获取所有记录。之后我想创建新的排序数组或对象数组。这些记录可以具有相同的参数名称,如 "startNum"。我怎样才能对具有相同参数的值求和并计算每个值的平均值?

我尝试使用 Javascript for 循环,但我只从具有相同 "startNum" 参数的数据库中获得了具有此结果值的数组,但其中很少有我不想要的空格- 就像 [2, , ,5]。我认为这可以做得更容易。如果它是使用 underscorejs 制作的,那就太好了。

这是我的尝试:

stars.find({}, function(error, result) {
               if(error) {
                 console.log(error);
               }
               var tmp = {};
               var a = [];
               One = {};
               var snOne = [];
               Two = {};
               var snTwo = [];
               Three = {};
               var snThree = [];
               var Four = {};
               var snFour = [];
               var Five = {};
               var snFive = [];

              for (var s = 0; s < result.length; s ++) {
                if (result[s].startingNumber === 1) {
                  snOne[0] = 1; // numer startowy konia
                  snOne[s+1]=(result[s].categoryOne + result[s].categoryTwo + result[s].categoryThree + result[s].categoryFour + result[s].categoryFive);
                }


                 if (result[s].startingNumber === 2) {
                  for (var q = 0; q < result.length; q ++) {
                  snTwo[0] = 2;
                  snTwo[q+1]=(result[q].categoryOne + result[q].categoryTwo + result[q].categoryThree + result[q].categoryFour + result[q].categoryFive);
                  }
                }

              for (var w = 0; w < result.length; w ++) {
                 if (result[w].startingNumber === 3) {
                  snThree[0] = 3;
                  snThree[w+1]=(result[w].categoryOne + result[w].categoryTwo + result[w].categoryThree + result[w].categoryFour + result[w].categoryFive);
                }
              }
                for (var e = 0; e < result.length; e ++) {
                 if (result[e].startingNumber === 4) {
                  snFour[0] = 4;
                  snFour[e+1]=(result[e].categoryOne + result[e].categoryTwo + result[e].categoryThree + result[e].categoryFour + result[e].categoryFive);
                }
              }
                for (var r = 0; r < result.length; r ++) {
                 if (result[r].startingNumber === 5) {
                  snFive[0] = 5;
                  snFive[r+1]=(result[r].categoryOne + result[r].categoryTwo + result[r].categoryThree + result[r].categoryFour + result[r].categoryFive);
                }
              }
              }// ..

我知道这种下划线排序方法,很有用,但不知道具体怎么做。

var sorted = _.sortBy(a, function(num) { return num; });

总而言之,我想计算每个 startingNum 类别的平均值。例如对象数组

第一个对象

{
    startingNum: 1,
counted_Average_Of_All_Existing_In_DataBase_Categories_From_One_To_Five_For_startingNum1: value
}

那些猫鼬结果看起来像:

[ {
categoryFive: 1,
categoryFour: 1,
categoryThree: 1,
categoryTwo: 1,
categoryOne: 1,
startingNumber: 1},... ]

我认为使用 underscorejs 会好得多。有人可以帮忙吗?我不知道该怎么做。

我假设您想查找按起始数字分组的所有类别的总分。如果是这样,这里使用 underscore.js

解决方案
// group by startingNumber
// each group will have multiple objects denoted by 'objs'
var grouped = _.chain(data).groupBy('startingNumber').map(function (objs, startNum) {
    // iterate through the objects for the current starting number
    var score = _.chain(objs).map(function (obj) {
        // remove all keys which are not starting with category
        var obj    = _.pick(obj, function (value, key) {
            return key.indexOf('category') !== -1;
        });
        var scores = _.values(obj); // get the scores for each category

        // compute the sum across all categories for this object
        return _.reduce(scores, function (memo, categoryScore) {
            return memo + categoryScore;
        }, 0);
        // compute the sum across all objects for this group
    }).reduce(function (memo, value) {
        return memo + value;
    }, 0).value();

    return {
        start: startNum,
        score: score
    };
}).value();

我看到您已经编写了 javascript 循环代码以按 startingNumber 对您的文档进行分组,然后对类别值求和,您只是想了解如何使用 underscore.js 对文档进行最佳排序。

不过,我相信使用MongoDB的聚合框架来为您进行分组、求和和排序会更好更简单。您还说过您想要一个 计数平均值 所以我的示例代码也计算计数和平均值。

如果我加载您的示例数据:

db.catdata.insert([
  {categoryFive:   1, categoryFour:   1, categoryThree:   1, 
   categoryTwo:    1, categoryOne:    1, startingNumber:  1},
  {categoryFive:   2, categoryFour:   1, categoryThree:   2, 
   categoryTwo:    1, categoryOne:    2, startingNumber:  1},
  {categoryFive:   1, categoryFour:   1, categoryThree:   1, 
   categoryTwo:    1, categoryOne:    1, startingNumber:  2},
  {categoryFive:  20, categoryFour:   1, categoryThree:  20, 
   categoryTwo:   20, categoryOne:   20, startingNumber:  1},
  {categoryFive: 100, categoryFour: 100, categoryThree: 100, 
   categoryTwo:  100, categoryOne:  100, startingNumber:  2}
]) ;

然后这个语句:

db.catdata.aggregate([
    {"$project" : {"startingNumber":1,
           "cats1to5":{$add:["$categoryFive", "$categoryFour", 
           "$categoryThree", "$categoryTwo",  "$categoryOne"]}
                  }
    }
   ,{"$group": {"_id"  : "$startingNumber",  "cntCat":{$sum:1},
                "totCat":{$sum:"$cats1to5"}, "avgCat":{$avg:"$cats1to5"}
               }
    }
   ,{$sort : {startingNumber:1}}
]);

产生这个输出:

{ "_id" : 2, "cntCat" : 2, "totCat" : 505, "avgCat" : 252.5 }
{ "_id" : 1, "cntCat" : 3, "totCat" : 94, "avgCat" : 31.333333333333332 }