Javascript JS 日期数组如何按天分组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31890076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Array Of JS Dates How To Group By Days
提问by Mark
I'm trying to figure out the most optimal and with as minimum amount of loops way to group my array of js dates objects from this: (Take a note this is browser console output it's actully real JS dates like new Date())
我试图找出最佳的和最少的循环方式来分组我的 js 日期对象数组:(注意这是浏览器控制台输出,它实际上是真实的 JS 日期,如 new Date())
[Sat Aug 08 2015 08:30:00 GMT+0200 (Central Europe Daylight Time), Sat Aug 08 2015 09:30:00 GMT+0200 (Central Europe Daylight Time), Sun Aug 09 2015 08:30:00 GMT+0200 (Central Europe Daylight Time), Sun Aug 09 2015 09:30:00 GMT+0200 (Central Europe Daylight Time), Mon Aug 10 2015 18:00:00 GMT+0200 (Central Europe Daylight Time), Mon Aug 10 2015 23:00:00 GMT+0200 (Central Europe Daylight Time), Tue Aug 11 2015 18:00:00 GMT+0200 (Central Europe Daylight Time), Tue Aug 11 2015 23:00:00 GMT+0200 (Central Europe Daylight Time), Wed Aug 12 2015 18:00:00 GMT+0200 (Central Europe Daylight Time), Wed Aug 12 2015 23:00:00 GMT+0200 (Central Europe Daylight Time)]
to oragnized array with each date of the same day inside a "chunk" so I can display it on the UI "Aug 08" and show 2 or how many dates inside that day.
到“块”中同一天的每个日期的组织数组,以便我可以在用户界面“8 月 8 日”上显示它并显示 2 或当天内有多少个日期。
for example:
例如:
[{day: 'Aug 08', times:[Sat Aug 08 2015 08:30:00 GMT+0200 (Central Europe Daylight Time), Sat Aug 08 2015 09:30:00 GMT+0200 (Central Europe Daylight Time)]}]
My current way I thought about doing it was
我目前考虑这样做的方式是
var startDays = _.map(occurences, function (date) {
return moment(date).startOf('day').format();
});
After that to get unique days:
之后获得独特的日子:
_.uniq(startDays, true)
and after I got the unique days another loop to add the same day to this group as you can see by now you might see why I don't like it and this is why I would love to get some smart help because nothing gets to my head with this. Thank you.
在我获得了独特的日子之后,另一个循环将同一天添加到这个组中,正如您现在看到的那样,您可能会明白为什么我不喜欢它,这就是为什么我很想得到一些聪明的帮助,因为我什么也得不到用这个头。谢谢你。
回答by Gruff Bunny
Underscore has the _.groupByfunction which should do exactly what you want:
下划线具有_.groupBy函数,它应该完全符合您的要求:
var groups = _.groupBy(occurences, function (date) {
return moment(date).startOf('day').format();
});
This will return an object where each key is a day and the value an array containing all the occurrences for that day.
这将返回一个对象,其中每个键是一天,值是一个包含当天所有事件的数组。
To transform the object into an array of the same form as in the question you could use map:
要将对象转换为与问题中形式相同的数组,您可以使用 map:
var result = _.map(groups, function(group, day){
return {
day: day,
times: group
}
});
To group, map and sort you could do something like:
要分组、映射和排序,您可以执行以下操作:
var occurrenceDay = function(occurrence){
return moment(occurrence).startOf('day').format();
};
var groupToDay = function(group, day){
return {
day: day,
times: group
}
};
var result = _.chain(occurences)
.groupBy(occurrenceDay)
.map(groupToDay)
.sortBy('day')
.value();
回答by RobG
Presuming your data is actually strings, I don't know why you think you need either of those libraries. You are just grouping strings based on substrings.
假设您的数据实际上是字符串,我不知道您为什么认为您需要这些库中的任何一个。您只是根据子字符串对字符串进行分组。
ES5 introduced reduce, which is great for accumulating things:
ES5 引入了reduce,它非常适合积累:
A helper to create an array of dates:
创建日期数组的助手:
// Generate a dates array given a start date and how many to create:
function genDates(startDate, count) {
var d = new Date(+startDate),
dates = [d];
for (var i=0; i<count; i++) {
d = new Date(+d);
d.setHours(d.getHours() + 10);
dates.push(d);
}
return dates;
}
This answer originally dealt with strings, modified to work with Dates:
这个答案最初处理字符串,修改后与日期一起使用:
// Generate date key 'MMM dd'
// Replaces use of moment.js
function getDateKey(date) {
var d = date.getDate();
var m = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
return m[date.getMonth()] + ' ' + ((d<10?'0':'') + d);
}
// Generate an array in format [{day:'MMM dd', times:[d0, d1, ...]}, ...]
// Replaces use of underscore.js
var obj = dates.reduce(function(acc, d) {
var p = getDateKey(d)
if (!acc[0].hasOwnProperty(p)) acc[0][p] = [];
acc[0][p].push(d);
return acc;
},[{}])
.reduce(function(acc, v){
Object.keys(v).forEach(function(k){acc.push({day:k, times:v[k]})});
return acc;
},[]);
console.log(JSON.stringify(obj));
If optimal performance is the key, the above is 20 times fasterthan the underscore + Moment solution for an array of 5 to 100 dates. To make it faster, remove all use of iterators and libraries and use a single function with for loops. Note that the above is only one line of code longer than the solution using Moment.js and underscore.js.
如果最佳性能是关键,那么对于 5 到 100 个日期的数组,上述方法比下划线 + Moment 解决方案快 20 倍。为了使它更快,删除所有迭代器和库的使用,并使用一个带有 for 循环的函数。请注意,上面的代码仅比使用 Moment.js 和 underscore.js 的解决方案长一行代码。
回答by Niklavr
If you need to grouping also by yearor (and) monthwith day - I recommend to use my solution.
如果您还需要按年或(和)月与日分组- 我建议使用我的解决方案。
In answers above if you'll get different month or year with the same day - your grouping will be incorrect.
在上面的答案中,如果您在同一天得到不同的月份或年份 - 您的分组将不正确。
Look at the good solution:
看看好的解决方案:
_.groupBy(arrayOfDates, function (el) {
return (el.getFullYear() + '|y|') + (el.getMonth() + '|m|') + (el.getDate() + '|d|');
});
What I do here? Just create an unique keys for each date, which includes: year, month and day. And then I group an array by this unique key.
我在这里做什么?只需为每个日期创建一个唯一的键,其中包括:年、月和日。然后我通过这个唯一键对数组进行分组。
回答by SergeyAn
Why do need this optimization? If your array is not large enoguh than you probably don't need to optimize your algorithm.
为什么需要这个优化?如果您的数组不是很大,那么您可能不需要优化算法。
I am not familiar with the given js libraries, but you can group your array by days with one loop. But you need to somehow determine the current day in the array and then create corresponding js object with a day-field and a times-array field and then add this object to your resulting array. It will be much faster if you presort your array before implementing this algorithm.
我不熟悉给定的 js 库,但是您可以使用一个循环按天对数组进行分组。但是您需要以某种方式确定数组中的当前日期,然后使用 day-field 和 times-array 字段创建相应的 js 对象,然后将此对象添加到结果数组中。如果在实现此算法之前对数组进行预排序,速度会快得多。