如何按天,周,月将对象与时间戳属性分组?

在nodejs应用程序中,我有一个事件对象的数组格式如下:

eventsArray = [ {id: 1, date: 1387271989749 }, {id:2, date: 1387271989760}, ... ] 

eventsArray具有n个元素的可变长度,假设我select时间参考是巴黎时间,我希望能够按日,周或月分组元素:

 groupedByDay = { 2012: { ... }, 2013: { dayN : [{id: a0, date: b0}, {id: a1, date: b1}, {id: a2, date: b2 }], dayN+1: [{id: a3, date: b3}, {id: a4, date: b4}, {id: a5, date: b5 }], ... }, 2014: { ... } } groupedByWeek = { 2012: { ... } 2013: { weekN: [{id: a0, date: b0}, {id: a1, date: b1}, {id: a2, date: b2 }], weekN+1: [{id: a3, date: b3}], .... }, 2014: { ... } } groupedByMonth = { 2012: { ... }, 2013: { monthN: [ {id: a0, date: b0 }, {id: a1, b1}, {id: a2, b2}, {id: a3, b3 }], monthN+1: [ {id: a4, date: b4 }, {id: a5, b5}, {id: a6, b6}], ... }, 2014: { ... } } 

对于操作unix时间戳的经验很less,我想知道如何做到这一点,或者如果有一个npm模块,会使这更容易。

这是我的解决scheme。 请记住,一天,一周和一个月是相对于起源,因为时代:

 eventsArray = [ {id: 1, date: 1387271989749 }, {id:2, date: 1387271989760} ]; byday={}; byweek={}; bymonth={}; function groupday(value, index, array) { d = new Date(value['date']); d = Math.floor(d.getTime()/(1000*60*60*24)); byday[d]=byday[d]||[]; byday[d].push(value); } function groupweek(value, index, array) { d = new Date(value['date']); d = Math.floor(d.getTime()/(1000*60*60*24*7)); byweek[d]=byweek[d]||[]; byweek[d].push(value); } function groupmonth(value, index, array) { d = new Date(value['date']); d = (d.getFullYear()-1970)*12 + d.getMonth(); bymonth[d]=bymonth[d]||[]; bymonth[d].push(value); } eventsArray.map(groupday); eventsArray.map(groupweek); eventsArray.map(groupmonth); 

以上所有的解决scheme都是非常纯粹的JS和香草解决scheme。 如果你可以使用一些库,那么lodash和moment可以一起用于简单的一行:

ES6

 let groupedResults = _.groupBy(results, (result) => moment(result['Date'], 'DD/MM/YYYY').startOf('isoWeek')); 

老JS

 var groupedResults = _.groupBy(results, function (result) { return moment(result['Date'], 'DD/MM/YYYY').startOf('isoWeek'); }); 

这将导致一个Mon Jul 25 2016 00:00:00 GMT+0100开始的数组,如Mon Jul 25 2016 00:00:00 GMT+0100 。 我相信你可以研究如何扩展它以获得数月,数年等。

RE:@SaintScott的评论

在评论中提到,这并不直接回答这个问题,因为原始使用UTC时间戳而不是格式化的date。 在这种情况下,您应该使用moment()而不使用第二个参数:

 moment(1387271989749).startOf('isoWeek'); 

或者如果使用UNIX时间戳,如下所示:

 moment.unix(yourTimestamp).startOf('isoWeek'); 

…虽然这是开始进一步从这个问题进一步到Moment文档,如果你想使用这种方法,我build议阅读。

我会做这样的事情:

 var item, i = 0, groups = {}, year, day; while (item = eventsArray[i++]) { item = new Date(item.date); year = item.getFullYear(); day = item.getDate(); groups[year] || (groups[year] = {}); // exists OR create {} groups[year][day] || (groups[year][day] = []); // exists OR create [] groups[year][day].push(item); } 

此版本仅按天分组,但您可以轻松地获得几周和几个月的相同结果,并使用相应的函数replaceitem.getDate()

  • getWeek() : https : getWeek()
  • getMonth() : MDN文档 (从零开始!)。

像这样的东西可能接近你所需要的东西。

JavaScriptdategetFullYeargetDategetMonth函数( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date ),你也可以看看这个SOpost( 转换Unix时间戳到JavaScript的时间 )。

这里的基本方法(安排)是按年份,然后按date和月份来build立哈希。

这段代码不会做星期。 你是指一年中的哪一周或哪一个月? 我怀疑你可以写自己的date方法来抓取这个数字,然后按照下面的模式抓取所有你想要的数据。 你可以从JS( getDay )得到星期getDay 。 我不知道你想如何计算一周,但这种方法可能会有所帮助。

我在浏览器中运行这个代码(在初始化一组dummyArray之后),但是我怀疑它会转化为节点。

你应该正确命名空间函数,如果你这么倾向,你可以把所有的方法移动到对象原型中。

希望这可以帮助

 var groupEvents = function(eventsArray) { this.dates = eventsArray; this.arranged = {}; this.monthKey = function(month) { return 'month' + month; }; this.dayKey = function(month) { return 'day' + month; }; this.getYear = function(year) { this.arranged[year] = this.arranged[year] || {} return this.arranged[year] }; this.getMonth = function(month, year) { var y = this.getYear(year); var k = this.monthKey(month); y[k] = y[k] || []; return y[k] }; this.getDate = function(day, year) { var y = this.getYear(year); var k = this.dayKey(day); y[k] = y[k] || []; return y[k] }; this.addToMonth = function(info, month, year) { var y = this.getMonth(month,year); y.push(info); }; this.addToDay = function(info, day, year) { var y = this.getDate(day,year); y.push(info); }; this.breakdownDate = function(date) { return { month: date.getMonth(), day: date.getDate(), year: date.getFullYear() }; } /** grab a date, break it up into day, month year and then categorize it */ this.arrange = function() { if(!this.arranged.length) { var ii = 0; var nn = this.dates.length; for(; ii < nn; ++ii ) { var el = this.dates[ii]; var date = new Date(el.date * 1000); var parsed = this.breakdownDate(date); this.addToMonth(el, parsed.month, parsed.year); this.addToDay(el, parsed.month, parsed.year); } } return this.arranged; }; return this; }; if(eventArray.length) { var events = new groupEvents(eventArray); var arranged = events.arrange(); console.log(arranged); } 

在@ user568109的答案上进行了扩展,这个答案是正确的,并且是正确的,下面是一个完成这个工作函数,为了演示,用一个更大的数组:

 // Group by time period - By 'day' | 'week' | 'month' | 'year' // ------------------------------------------------------------ var groupByTimePeriod = function (obj, timestamp, period) { var objPeriod = {}; var oneDay = 24 * 60 * 60 * 1000; // hours * minutes * seconds * milliseconds for (var i = 0; i < obj.length; i++) { var d = new Date(obj[i][timestamp] * 1000); if (period == 'day') { d = Math.floor(d.getTime() / oneDay); } else if (period == 'week') { d = Math.floor(d.getTime() / (oneDay * 7)); } else if (period == 'month') { d = (d.getFullYear() - 1970) * 12 + d.getMonth(); } else if (period == 'year') { d = d.getFullYear(); } else { console.log('groupByTimePeriod: You have to set a period! day | week | month | year'); } // define object key objPeriod[d] = objPeriod[d] || []; objPeriod[d].push(obj[i]); } return objPeriod; }; var eventsArray = [{ id: 1, date: 1317906596 }, { id: 2, date: 1317908605 }, { id: 3, date: 1317909229 }, { id: 4, date: 1317909478 }, { id: 5, date: 1317909832 }, { id: 6, date: 1317979141 }, { id: 7, date: 1317979232 }, { id: 8, date: 1317986965 }, { id: 9, date: 1318582119 }, { id: 10, date: 1318595862 }, { id: 11, date: 1318849982 }, { id: 12, date: 1318855706 }, { id: 13, date: 1318929018 }, { id: 14, date: 1318933265 }, { id: 15, date: 1318940511 }, { id: 16, date: 1318945096 }, { id: 17, date: 1319017541 }, { id: 18, date: 1319527136 }, { id: 19, date: 1318582119 }, { id: 20, date: 1318595862 }, { id: 21, date: 1318582119 }, { id: 22, date: 1318595862 }, { id: 23, date: 1319713399 }, { id: 24, date: 1320053428 }, { id: 25, date: 1320333481 }, { id: 26, date: 1320832755 }, { id: 27, date: 1321012378 }, { id: 28, date: 1321280993 }, { id: 29, date: 1321347659 }, { id: 30, date: 1321350476 }, { id: 31, date: 1321369307 }, { id: 32, date: 1321369614 }, { id: 33, date: 1321610123 }, { id: 34, date: 1321613205 }, { id: 35, date: 1321617250 }, { id: 36, date: 1321626603 }, { id: 37, date: 1321865808 }, { id: 38, date: 1321876609 }, { id: 39, date: 1321877598 }, { id: 40, date: 1321877832 }, { id: 41, date: 1321953322 }, { id: 42, date: 1322061969 }, { id: 43, date: 1322142603 }, { id: 44, date: 1322211686 }, { id: 45, date: 1322213793 }, { id: 46, date: 1322214569 }, { id: 47, date: 1322482817 }, { id: 48, date: 1322663742 }, { id: 49, date: 1322664267 }, { id: 50, date: 1322747231 }, { id: 51, date: 1322819964 }, { id: 52, date: 1323358224 }, { id: 53, date: 1323681272 }, { id: 54, date: 1323695093 }, { id: 55, date: 1323696589 }, { id: 56, date: 1323763763 }, { id: 57, date: 1322819964 }, { id: 58, date: 1323681272 }, { id: 59, date: 1323851164 }, { id: 60, date: 1323853123 }, { id: 61, date: 1323854271 }, { id: 62, date: 1323858072 }, { id: 63, date: 1325690573 }, { id: 64, date: 1325751893 }, { id: 65, date: 1325760204 }, { id: 66, date: 1325769098 }, { id: 67, date: 1325769981 }, { id: 68, date: 1325771632 }, { id: 69, date: 1325776473 }, { id: 70, date: 1325837346 }, { id: 71, date: 1326110199 }, { id: 72, date: 1326793097 }, { id: 73, date: 1326878182 }, { id: 74, date: 1326881341 }, { id: 75, date: 1326975873 }, { id: 76, date: 1326985667 }, { id: 77, date: 1327047585 }, { id: 78, date: 1327062945 }, { id: 79, date: 1327063660 }, { id: 80, date: 1327322844 }, { id: 81, date: 1327326904 }, { id: 82, date: 1327329215 }, { id: 83, date: 1327397042 }, { id: 84, date: 1327399839 }, { id: 85, date: 1327401818 }, { id: 86, date: 1327407161 }, { id: 87, date: 1327419420 }, { id: 88, date: 1327570243 }, { id: 89, date: 1327578536 }, { id: 90, date: 1327584554 }, { id: 91, date: 1327914616 }, { id: 92, date: 1327917019 }, { id: 93, date: 1327931685 }, { id: 94, date: 1327933025 }, { id: 95, date: 1327934772 }, { id: 96, date: 1327947074 }, { id: 97, date: 1328626734 }, { id: 98, date: 1328626734 }, { id: 99, date: 1330070074 }, { id: 100, date: 1330073135 }, { id: 101, date: 1330073259 }, { id: 102, date: 1330332445 }, { id: 103, date: 1330351925 }, { id: 104, date: 1330420928 }, { id: 105, date: 1330423209 }, { id: 106, date: 1330437337 }, { id: 107, date: 1330439446 }]; var objPeriodDay = groupByTimePeriod(eventsArray, 'date', 'day'); var objPeriodWeek = groupByTimePeriod(eventsArray, 'date', 'week'); var objPeriodMonth = groupByTimePeriod(eventsArray, 'date', 'month'); var objPeriodYear = groupByTimePeriod(eventsArray, 'date', 'year'); console.log(objPeriodDay); console.log(objPeriodWeek); console.log(objPeriodMonth); console.log(objPeriodYear); 

这里有一个小提琴 (你将不得不打开控制台看到输出)。

正如你将在小提琴中看到的那样,4个物体的键将如下所示:

  • objPeriodDay :1970年1月1日以来的天数
  • objPeriodWeek :相对于1970年1月1日第一周的周数
  • objPeriodMonth :1970年1月1日以来的月份数
  • objPeriodYear :今年

请注意,所有这四个变化会给你独特的钥匙。 例如,月份会给你“2011年12月”(自1970年1月1日以来的月份),而不仅仅是“十二月”。