简体   繁体   English

如何在Javascript中合并键并添加其值?

[英]How Can I Merge Key and Add Up Their Values in Javascript?

So when I GET my data back from the database I get this: 因此,当我从数据库取回数据时,我得到了:

{
"times": [
    {
        "userName": "jon",
        "gameName": "halo",
        "time": "00.00.06"
    },
    {
        "userName": "jon",
        "gameName": "call of duty",
        "time": "00.00.05"
    },
    {
        "userName": "cody",
        "gameName": "thing1",
        "time": "00.00.07"
    },
    {
        "userName": "jon",
        "gameName": "war game",
        "time": "00.00.08"
    },
    {
        "userName": "jon",
        "gameName": "a game 22",
        "time": "00.00.08"
    },
    {
        "userName": "jon",
        "gameName": "monster",
        "time": "00.00.05"
    },
    {
        "userName": "jon",
        "gameName": "call of duty",
        "time": "00.00.06"
    },
    {
        "userName": "jon",
        "gameName": "war game",
        "time": "00.00.03"
    },
    {
        "userName": "guy",
        "gameName": "game1",
        "time": "00.00.03"
    },
    {
        "userName": "fun",
        "gameName": "My Game",
        "time": "00.00.05"
    },
    {
        "userName": "jon",
        "gameName": "Horizon: Zero Dawn",
        "time": "00.00.10"
    },
    {
        "userName": "jon",
        "gameName": "Horizon: Zero Dawn",
        "time": "00.02.10"
    },
    {
        "userName": "jon",
        "gameName": "Paragon",
        "time": "00.00.07"
    },
    {
        "userName": "jon",
        "gameName": "Paragon",
        "time": "00.00.11"
    },
    {
        "userName": "jon",
        "gameName": "halo",
        "time": "00.00.05"
    }
]

} }

I want to be able to sum up all "times" for each game and display it as such: "GameName": "All times summed up for specific game" 我希望能够总结每个游戏的所有“时间”,并显示为:“ GameName”:“所有时间都归于特定游戏”

Is there any way to do this? 有什么办法吗?

You can use lodash to get desired output. 您可以使用lodash获得所需的输出。

 const obj = { "times": [ { "userName": "jon", "gameName": "halo", "time": "00.00.06" }, { "userName": "jon", "gameName": "call of duty", "time": "00.00.05" }, { "userName": "cody", "gameName": "thing1", "time": "00.00.07" }, { "userName": "jon", "gameName": "war game", "time": "00.00.08" }, { "userName": "jon", "gameName": "a game 22", "time": "00.00.08" }, { "userName": "jon", "gameName": "monster", "time": "00.00.05" }, { "userName": "jon", "gameName": "call of duty", "time": "00.00.06" }, { "userName": "jon", "gameName": "war game", "time": "00.00.03" }, { "userName": "guy", "gameName": "game1", "time": "00.00.03" }, { "userName": "fun", "gameName": "My Game", "time": "00.00.05" }, { "userName": "jon", "gameName": "Horizon: Zero Dawn", "time": "00.00.10" }, { "userName": "jon", "gameName": "Horizon: Zero Dawn", "time": "00.02.10" }, { "userName": "jon", "gameName": "Paragon", "time": "00.00.07" }, { "userName": "jon", "gameName": "Paragon", "time": "00.00.11" }, { "userName": "jon", "gameName": "halo", "time": "00.00.05" } ]}; const times = _.groupBy(obj.times, "gameName"); let game_times = {}; for(key in times){ game_times[key] = _.reduce(times[key], (sum, time)=> { time = time.time.split("."); sum = sum.split("."); let total = ""; let ss = parseInt(sum[2]) + parseInt(time[2]); let mm = parseInt(sum[1]) + parseInt(time[1]); let hh = parseInt(sum[0]) + parseInt(time[0]); mm += parseInt(ss / 60); hh += parseInt(mm / 60); ss = ss % 60; return hh + "." + mm + "." + ss; },"00.00.00"); } console.log(game_times); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> 

Loop through your array and access the time property on each item then just add each amount. 遍历数组并访问每个项目的time属性,然后仅添加每个数量。

Something similar to this 与此类似

var total;
for (var i = 0; i < times.length; i++) {
    var itemTime = times[i].time;
    //parse time into int or date before adding otherwise it'll concatenate the string 
    total += itemTime;

} }

Then retrieve the element in which you want to display the time and s set the value 然后检索要在其中显示时间的元素并设置值

  var element = document.getElementById("idOfElementToDisplayTotalTime");
   element.innerHTML = "All times summed: " + total;

Hope that helps or at least points you in the right direction. 希望能对您有所帮助或至少为您指明正确的方向。 Sorry for any typos and laziness as I typed this up on my phone. 很抱歉,我在手机上输入错字和懒惰。

This is a perfect situation for a reducer function. 这是减速器功能的理想情况。 I've added a runnable snippet below but the relevant code is: 我在下面添加了一个可运行的代码段,但相关代码为:

const parseSeconds = timeStr => {
    const regex = /(\d\d)\.(\d\d)\.(\d\d)/;
    const [original, hours, mins, secs] = regex.exec(timeStr);
    return (3600 * hours) + (60 * mins) + Number(secs);
}

const r = data.times
.map(({ gameName, time }) => ({
    gameName,
    time: parseSeconds(time)
}))
.reduce((results, { gameName, time }) => {
    if (!results.hasOwnProperty(gameName)) {
        results[gameName] = 0;
    }
    results[gameName] += time;
    return results;
}, {});

 const data = { "times": [ { "userName": "jon", "gameName": "halo", "time": "00.00.06" }, { "userName": "jon", "gameName": "call of duty", "time": "00.00.05" }, { "userName": "cody", "gameName": "thing1", "time": "00.00.07" }, { "userName": "jon", "gameName": "war game", "time": "00.00.08" }, { "userName": "jon", "gameName": "a game 22", "time": "00.00.08" }, { "userName": "jon", "gameName": "monster", "time": "00.00.05" }, { "userName": "jon", "gameName": "call of duty", "time": "00.00.06" }, { "userName": "jon", "gameName": "war game", "time": "00.00.03" }, { "userName": "guy", "gameName": "game1", "time": "00.00.03" }, { "userName": "fun", "gameName": "My Game", "time": "00.00.05" }, { "userName": "jon", "gameName": "Horizon: Zero Dawn", "time": "00.00.10" }, { "userName": "jon", "gameName": "Horizon: Zero Dawn", "time": "00.02.10" }, { "userName": "jon", "gameName": "Paragon", "time": "00.00.07" }, { "userName": "jon", "gameName": "Paragon", "time": "00.00.11" }, { "userName": "jon", "gameName": "halo", "time": "00.00.05" } ] }; const parseSeconds = timeStr => { const regex = /(\\d\\d)\\.(\\d\\d)\\.(\\d\\d)/; const [original, hours, mins, secs] = regex.exec(timeStr); return (3600 * hours) + (60 * mins) + Number(secs); } const r = data.times .map(({ gameName, time }) => ({ gameName, time: parseSeconds(time) })) .reduce((results, { gameName, time }) => { if (!results.hasOwnProperty(gameName)) { results[gameName] = 0; } results[gameName] += time; return results; }, {}); console.log(r); 

You can use Javascript's Array.prototoype.reduce method like so: 您可以像这样使用Javascript的Array.prototoype.reduce方法:

const gameTimes = data.times.reduce(function(totalTimes, item) {
    if (!totalTimes.hasOwnProperty(item.gameName)) {
        totalTimes[item.gameName] = 0;
    }
    totalTimes[item.gameName] += item.time;
    // you'll notice that I just directly added the time above, but your time
    // is formatted as e.g. "00.00.10". You'll have to come up with a way to
    // add times that are formatted in that way. The previous line just shows
    // where you should update the total time. :)
    return totalTimes;
}, {});

/*
gameTimes => {
    "Call of Duty": "00.00.10",
    "Horizon: Zero Dawn": "00.10.00",
    ...
}
*/

This will result into a new object whose keys are the names of the games and the values are the total times. 这将导致一个新对象,其键是游戏名称,值是总时间。 As noted in my comment in the code snippet, you'll have to find a way to add the times based on your time format which looks like 00.00.10 . 正如我在代码片段中的注释中所指出的那样,您将必须找到一种方法来根据您的时间格式(类似于00.00.10添加时间。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM