【问题标题】:How can I sum these Javascript values?如何对这些 Javascript 值求和?
【发布时间】:2017-09-22 11:38:19
【问题描述】:

我有以下对象数组。每个对象中都有一对可供两个人使用的对象。它保存分数,例如Bob 的第 1 场比赛有 10 分,然后第 2 场比赛有 9 分等。

var arr = [{
  "bob": {
    "1": "10",
    "2": "9",
    "3": "9",
    "4": "10",
    "5": "9",
    "6": "7",
    "7": "10",
    "8": "10",
    "9": "10",
    "10": "9",
    "11": "10",
    "12": "8"
  },
  "max": {
    "1": "9",
    "2": "10",
    "3": "10",
    "4": "8",
    "5": "10",
    "6": "10",
    "7": "8",
    "8": "9",
    "9": "9",
    "10": "10",
    "11": "9",
    "12": "10"
  }
},

{
  "bob": {
    "1": "10",
    "2": "9",
    "3": "9",
    "4": "10",
    "5": "9",
    "6": "7",
    "7": "10",
    "8": "10",
    "9": "10",
    "10": "9",
    "11": "10",
    "12": "8"
  },
  "max": {
    "1": "9",
    "2": "10",
    "3": "10",
    "4": "8",
    "5": "10",
    "6": "10",
    "7": "8",
    "8": "9",
    "9": "9",
    "10": "10",
    "11": "9",
    "12": "10"
  }
},
{
  "bob": {
    "1": "10",
    "2": "9",
    "3": "9",
    "4": "10",
    "5": "9",
    "6": "7",
    "7": "10",
    "8": "10",
    "9": "10",
    "10": "9",
    "11": "10",
    "12": "8"
  },
  "max": {
    "1": "9",
    "2": "10",
    "3": "10",
    "4": "8",
    "5": "10",
    "6": "10",
    "7": "8",
    "8": "9",
    "9": "9",
    "10": "10",
    "11": "9",
    "12": "10"
  }
}
]

如何循环遍历每对对象(bob 和 max)并创建所有对象的平均值?我发现循环内的循环真的很混乱......我正在努力如何写这个问题。

最终目标是拥有一对对象,其值将从数组中所有先前的对象中取平均值。例如,对于每个人,我需要将每个人的分数相加(分数 1 - 12),然后创建一个最终的平均分数。我希望这是有道理的?就我所尝试的而言,我尝试操纵许多其他 SO 答案以满足我的需求,但我一直在错误地遇到错误,因此不值得与此一起发布......

 // Final averaged scores for each person based on the total data available
[{
  "bob": {
    "1": "10",
    "2": "9",
    "3": "9",
    "4": "10",
    "5": "9",
    "6": "7",
    "7": "10",
    "8": "10",
    "9": "10",
    "10": "9",
    "11": "10",
    "12": "8"
  },
  "max": {
    "1": "9",
    "2": "10",
    "3": "10",
    "4": "8",
    "5": "10",
    "6": "10",
    "7": "8",
    "8": "9",
    "9": "9",
    "10": "10",
    "11": "9",
    "12": "10"
  }
}]

【问题讨论】:

  • 如果要使用数字键,为什么不使用数组?
  • 因为它在脚本的其他地方与此问题无关。
  • 我不清楚你的目标。您是否想要 Bob 的所有“1”、“2”等分数的平均值(Max 也一样)?
  • 是的,所以...取每个对象中的所有 bobs 分数并创建一个平均分数对象,例如
  • 为什么将分数存储为字符串?这种数据结构确实效率低下。

标签: javascript jquery json object


【解决方案1】:

您可以采用单循环方法来计算所需的平均值。该提案采用 ES5。

变量:

  • r:临时结果在Array#reduce
  • o:对象,数组的一项,
  • a: 调用数组的引用,长度需要,
  • kl:嵌套对象的键。

模式:

var array = [{ bob: { 1: "10", 2: "9", 3: "9", 4: "10", 5: "9", 6: "7", 7: "10", 8: "10", 9: "10", 10: "9", 11: "10", 12: "8" }, max: { 1: "9", 2: "10", 3: "10", 4: "8", 5: "10", 6: "10", 7: "8", 8: "9", 9: "9", 10: "10", 11: "9", 12: "10" } }, { bob: { 1: "10", 2: "9", 3: "9", 4: "10", 5: "9", 6: "7", 7: "10", 8: "10", 9: "10", 10: "9", 11: "10", 12: "8" }, max: { 1: "9", 2: "10", 3: "10", 4: "8", 5: "10", 6: "10", 7: "8", 8: "9", 9: "9", 10: "10", 11: "9", 12: "10" } }, { bob: { 1: "10", 2: "9", 3: "9", 4: "10", 5: "9", 6: "7", 7: "10", 8: "10", 9: "10", 10: "9", 11: "10", 12: "8" }, max: { 1: "9", 2: "10", 3: "10", 4: "8", 5: "10", 6: "10", 7: "8", 8: "9", 9: "9", 10: "10", 11: "9", 12: "10" } }],
    result = array.reduce(function (r, o, _, a) {
        Object.keys(o).forEach(function (k) {
            r[k] = r[k] || {};
            Object.keys(o[k]).forEach(function (l) {
                r[k][l] = (r[k][l] || 0) + o[k][l] / a.length;
            });
        });
        return r;
    }, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 这非常棒,但是在解释时,尽量不要使用单字母参数。它们让我们更难理解正在发生的事情。
【解决方案2】:
arr.reduce(function(res, obj, index, array) {
    Object.keys(obj).forEach(function(player) {
        res[player] = res[player] || {};
        Object.keys(obj[player]).forEach(function(game) {
            res[player][game] = res[player][game] || 0;
            res[player][game] += parseFloat(obj[player][game] / array.length);
        });
    });
    return res;
}, {});

【讨论】:

  • 这是正确的,因为除以多个数字的总和与将这些数字相加相同。 (a + b + c) / d = (a / d) + (b / d) + (c / d)
【解决方案3】:

我为此使用了基本循环:

var gameCount = arr.length;

var outPutArr = {"bob":{},"max":{}};

// Initialize the output array
for(var i=1;i<=Object.keys(arr[0].bob).length;i++)
{
    outPutArr["bob"][i+""] = "0";
    outPutArr["max"][i+""] = "0";
}

// Loop through all games and add score of bob and max
arr.forEach(function(item){
    for(var i=1;i<=Object.keys(arr[0].bob).length;i++)
    {
        outPutArr["bob"][i+""] = (parseInt(item["bob"][i+""]) + parseInt(outPutArr["bob"][i+""]))+"";
        outPutArr["max"][i+""] = (parseInt(item["max"][i+""]) + parseInt(outPutArr["max"][i+""]))+"";
    }
});

for(var i=1;i<=Object.keys(arr[0].bob).length;i++)
{
    outPutArr["bob"][i+""] = (parseInt(outPutArr["bob"] [i+""])/gameCount)+"";
    outPutArr["max"][i+""] = (parseInt(outPutArr["max"] [i+""])/gameCount)+"";
}

console.log(JSON.stringify(outPutArr));

【讨论】:

    【解决方案4】:

    您可以使用array.maparray.reduce 的组合来返回分数的总和。

    console.clear();
    
    var games = [
      {
        "bob": { "1": "10", "2": "9", "3": "9", "4": "10" },
        "max": { "1": "9", "2": "10", "3": "10", "4": "8" }
      },
      {
        "bob": { "1": "10", "2": "9", "3": "9", "4": "10" },
        "max": { "1": "9", "2": "10", "3": "10", "4": "8" }
      },
      {
        "bob": { "1": "10", "2": "9", "3": "9", "4": "10" },
        "max": { "1": "9", "2": "10", "3": "10", "4": "8" }
      }
    ];
    
    let scores = {};
    games.forEach( game => {
      Object.keys(game).forEach( player => {
        scores[player] = scores[player] || {};
        Object.keys(game[player]).forEach(gameNumber => {
          scores[player][gameNumber] = scores[player][gameNumber] || [];
          scores[player][gameNumber].push(parseInt(game[player][gameNumber]));
        });
      });
    });
    
    Object.keys(scores).forEach( player => {
      Object.keys(scores[player]).forEach(game => {
        let total = scores[player][game].reduce((a, b) => { return a+b; });
        let length = scores[player][game].length;
        
        scores[player][game] = total / length;
      });
    });
    
    console.info( scores );

    【讨论】:

    • 这是 ES5 语法吗?老实说,我不知道这是什么。
    • 看来我误解了你的问题,让我重新修改一下:-D
    • @ProEvilz 你有什么不明白的?
    • 我想我的大脑通常无法处理循环内的递归/循环。是什么||在这种情况下是什么意思?
    • @ProEvilz if (typeof scores[player] === 'undefined') { scores[player] = {}; } else { scores[player] = scores[player]; } 表示如果第一个值为falsey,则取第二个值。查看@NinaScholz 和@Ammar 的答案。
    【解决方案5】:

    这会是你想要的吗? 它会根据您拥有的游戏数量(只要不是每个对象超过 100 个)为您的用户求和,并将结果存储在 summs 对象中

    您可以通过fiddle在控制台中观察结果

    var arr = [{
      "bob": {
        "1": "10",
        "2": "9",
        "3": "9",
        "4": "10",
        "5": "9",
        "6": "7",
        "7": "10",
        "8": "10",
        "9": "10",
        "10": "9",
        "11": "10",
        "12": "8"
      },
      "max": {
        "1": "9",
        "2": "10",
        "3": "10",
        "4": "8",
        "5": "10",
        "6": "10",
        "7": "8",
        "8": "9",
        "9": "9",
        "10": "10",
        "11": "9",
        "12": "10"
      }
    },
    
    {
      "bob": {
        "1": "10",
        "2": "9",
        "3": "9",
        "4": "10",
        "5": "9",
        "6": "7",
        "7": "10",
        "8": "10",
        "9": "10",
        "10": "9",
        "11": "10",
        "12": "8"
      },
      "max": {
        "1": "9",
        "2": "10",
        "3": "10",
        "4": "8",
        "5": "10",
        "6": "10",
        "7": "8",
        "8": "9",
        "9": "9",
        "10": "10",
        "11": "9",
        "12": "10"
      }
    },
    {
      "bob": {
        "1": "10",
        "2": "9",
        "3": "9",
        "4": "10",
        "5": "9",
        "6": "7",
        "7": "10",
        "8": "10",
        "9": "10",
        "10": "9",
        "11": "10",
        "12": "8"
      },
      "max": {
        "1": "9",
        "2": "10",
        "3": "10",
        "4": "8",
        "5": "10",
        "6": "10",
        "7": "8",
        "8": "9",
        "9": "9",
        "10": "10",
        "11": "9",
        "12": "10"
      }
    }
    ]
    
    var summs = {};
    
    arr.forEach(function(users, ind, arr){
        for (var user in users) {
        if (users.hasOwnProperty(user)) {
          if (!summs.hasOwnProperty(user)) summs[user] = 0;
          console.log(users[user]);
            for (var i = 0; i < 100; i++){
                if (users[user].hasOwnProperty(i+'')){
                    summs[user] += parseInt(users[user][i]);
                }
          }
        }
      } 
    });
    console.log(summs);
    

    【讨论】:

      猜你喜欢
      • 2013-05-03
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 2022-11-18
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      相关资源
      最近更新 更多