简体   繁体   English

通过一个属性和求和值组合骨干模型

[英]Combine backbone models by one attribute and sum values

I have a collection where the models look like the following: 我有一个模型如下的集合:

ProfileStat = Backbone.Model.extend({
defaults: {
    sessionID: '',
    uID: '',
    keySig: '',
    tempo: '',
    time: '',
    datetime: ''
},
url: function() {
    return apiUrl('Sessions');
}
});

I would like to loop through all the models in this collection, combine all the models that have the same datetime, and add up all their time values. 我想遍历此集合中的所有模型,合并具有相同日期时间的所有模型,并将所有时间值相加。

To give you some context, we basically have users that are putting in sessions in our site, every session gets recorded with the amount of time they have played, but usually they are putting in around 10 sessions a day. 为了给您提供一些背景信息,我们基本上将一些用户放在我们的站点中,每个会话都记录有他们玩过的时间,但是通常他们每天大约进行10个会话。 We would like to combine all these sessions for any given day, and output the total time they have played into a graph. 我们希望将任意一天的所有这些会话合并在一起,并将它们的总播放时间输出到图表中。

Can anyone help me with a method to combine these models based on the day that the user has played, and add up all the time they have played for that given day? 谁能帮我找到一种方法,根据用户玩耍的日子来组合这些模型,并累计给定日期的所有玩耍时间? Thank you! 谢谢!

I combined usage of a few different underscore methods to do this. 我结合使用了几种不同的下划线方法来做到这一点。 Group by to group by the date, Map for creating objects that look exactly how we want, and reduce to sum the items. 分组以按日期分组,映射用于创建看起来完全像我们想要的对象,并减少总和。 Let me know if this all makes sense 让我知道这一切是否有意义

 arrayOfProfileStats = [{ defaults: { sessionID: '1', uID: '', keySig: '', tempo: '', time: '00:10:00', datetime: '01/01/2000' } }, { defaults: { sessionID: '2', uID: '', keySig: '', tempo: '', time: '00:10:00', datetime: '01/01/2000' } }, { defaults: { sessionID: '3', uID: '', keySig: '', tempo: '', time: '00:10:00', datetime: '01/02/2000' } } ]; function msToHMS(ms) { // 1- Convert to seconds: var seconds = ms / 1000; // 2- Extract hours: var hours = parseInt(seconds / 3600); // 3,600 seconds in 1 hour seconds = seconds % 3600; // seconds remaining after extracting hours // 3- Extract minutes: var minutes = parseInt(seconds / 60); // 60 seconds in 1 minute // 4- Keep only seconds not extracted to minutes: seconds = seconds % 60; return (hours + ":" + minutes + ":" + seconds); } function toMilliseconds(time) { var a = time.split(':'); // split it at the colons return ((parseInt(a[0]) * 60 * 60 + parseInt(a[1]) * 60 + parseInt(a[2])) * 1000); } var timeForEachDay = function() { var grouped = (_.groupBy(arrayOfProfileStats, function(stat) { return stat.defaults.datetime; })); return _.map(grouped, function(profileDate, key) { // At this point we should have a new object that groups the profileStats by datetime // Now we need to sum the times using reduce() return { [key]: msToHMS(_.reduce(_.map(profileDate, function(date) { return toMilliseconds(date.defaults.time); }), function(total, time) { return total + time; }, 0)) }; }); } console.log(timeForEachDay()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> 

I used a couple underscore methods to solve this problem. 我使用了几种下划线方法来解决此问题。 The first function filters through all the models in the collection to ensure that the models being grabbed are after a certain date. 第一个函数对集合中的所有模型进行过滤,以确保要捕获的模型在特定日期之后。 The second function sorts through all those chosen models, and sums up the time played. 第二个功能对所有选择的模型进行分类,并汇总播放时间。

filtered = this.filter(function (ProfileStat) {
        //convert the current models datetime to unix
        unixDateTime = Moment(ProfileStat.get("datetime")).valueOf();
        //convert the interval date to unix
        intervalDate = Moment(intervalDate).valueOf();
        //only return the sessions that are ahead of the interval date
        return unixDateTime >= intervalDate;

        //iterate through each model returned from the filtered function and combine all the sessions for any given date
    }).forEach(function(ProfileStat){
        //format the current model date time to MM/DD/YYYY
        ProfileStat.attributes.datetime = Moment(ProfileStat.get('datetime')).format('MM/DD/YYYY');
        //store this datetime in a variable
        var date = ProfileStat.attributes.datetime;
        if (dateArray.indexOf(date) == -1) {
             dateArray.push(date);
             var obj = {datetime: date, timePlayed: ProfileStat.attributes.timePlayed,};
             resultArray.push(obj);
         } 
         else {
             resultArray[dateArray.indexOf(date)].timePlayed += ProfileStat.attributes.timePlayed;
         }
    });

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

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