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

时间:2017-04-26 01:32:00

标签: javascript backbone.js underscore.js

我有一个集合,模型如下所示:

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

我想循环遍历此集合中的所有模型,组合具有相同日期时间的所有模型,并将所有时间值相加。

为了给你一些背景信息,我们基本上有用户在我们的网站上进行会话,每个会话都会记录他们播放的时间,但通常他们每天大约会话10次。我们希望在任何特定日期组合所有这些会话,并将他们播放的总时间输出到图表中。

任何人都可以帮助我根据用户玩的那天组合这些模型的方法,并将他们在特定日期玩的所有时间加起来吗?谢谢!

2 个答案:

答案 0 :(得分:0)

我结合使用了几种不同的下划线方法来完成这项工作。分组按日期分组,映射用于创建看起来完全符合我们需要的对象,并减少对项目的求和。如果这一切都有意义,请告诉我



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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我使用了几个下划线方法来解决这个问题。第一个函数过滤集合中的所有模型,以确保被抓取的模型在特定日期之后。第二个函数对所有选择的模型进行排序,并总结所播放的时间。

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