我试图按日期月份和周来对对象数组进行排序
myArray : [
{'name' : 'example1', 'date' : '2011-01-01'},
{'name' : 'example1', 'date' : '2011-01-02'},
{'name' : 'example1', 'date' : '2011-02-02'},
{'name' : 'example1', 'date' : '2011-02-15'},
{'name' : 'example1', 'date' : '2011-02-17'},
{'name' : 'example1', 'date' : '2012-01-01'},
{'name' : 'example1', 'date' : '2012-03-03'},
]
我希望得到这样的结果:
result : [{
'2011': { // Year 2011
'01': { // January
'01' : [ // First week of January
{'name' : 'example1', 'date' : '2011-01-01'},
{'name' : 'example1', 'date' : '2011-01-02'},
]
},
'02' : { // February
'01' : [ // First week of February
{'name' : 'example1', 'date' : '2011-02-02'},
],
'03' : [
{'name' : 'example1', 'date' : '2011-02-15'},
{'name' : 'example1', 'date' : '2011-02-17'},
]
}
},
'2012' : { // Year 2012
'01' : { // January
'01': [ // First week of January
{'name': 'example1', 'date': '2012-01-01'}
]
},
'03': { // March
'01' : [ // First week of March
{'name' : 'example1', 'date' : '2012-03-03'},
]
}
}
}]
我将lodash.groupBy
与return getISOWeek(obj.date)
或return getMonth(obj.date)
或return getYear(obj.date)
一起使用。
我设法按年,月,年和周对数据进行排序,但我无法弄清楚如何同时对三者进行排序。
感谢您的帮助
答案 0 :(得分:1)
您可以使用for..of
循环,String.prototype.match()
与RegExp
/\d+/
一起获取YYYY
和MM
部分"date"
适当的价值; Array.prototype.filter()
通过比较YYYY-MM
与for..of
和YYYY
连接,将输入数组中对象的"-"
与MM
循环的当前对象相匹配。
const myArray = [
{'name' : 'example1', 'date' : '2011-01-01'},
{'name' : 'example1', 'date' : '2011-01-02'},
{'name' : 'example1', 'date' : '2011-02-02'},
{'name' : 'example1', 'date' : '2011-02-15'},
{'name' : 'example1', 'date' : '2011-02-17'},
{'name' : 'example1', 'date' : '2012-01-01'},
{'name' : 'example1', 'date' : '2012-03-03'},
];
let res = {};
let fn = (year, month, o = res, array = myArray) => {
o[year][month] = {
[month]: array.filter(({date: d}) => `${year}-${month}` === d.slice(0, 7))
};
}
for (let {date} of myArray) {
let [year, month] = date.match(/\d+/g);
if (!res[year]) res[year] = {};
fn(year, month)
}
console.log(res);

jsfiddle https://jsfiddle.net/sd7e9Lp7/3/
答案 1 :(得分:1)
从你的问题中你真正不清楚你在追求什么。 ISO周数基于年,而不是数月,例如2011-01-01属于2010年的最后一周,而不是2011年的第一周。你真的无法按月分组和ISO周数,因为每年大约10周将从一个月开始,到另一个月结束。
如果您每天所处的“每周的一周”概念只是Math.ceil(day number / 7)
,那么您可以按此分组,并注意到2016年2月29日这样的日期将是第5周的唯一日期那年二月。
var data = [
{'name' : 'example1', 'date' : '2011-01-01'},
{'name' : 'example1', 'date' : '2011-01-02'},
{'name' : 'example1', 'date' : '2011-02-02'},
{'name' : 'example1', 'date' : '2011-02-15'},
{'name' : 'example1', 'date' : '2011-02-17'},
{'name' : 'example1', 'date' : '2012-01-01'},
{'name' : 'example1', 'date' : '2012-03-03'},
];
function groupByMonthWeek(data) {
var year, month, week
return data.reduce(function (acc, obj) {
var b = obj.date.split(/\D/);
// Get custom week number, zero padded
var weekNum = '0' + Math.ceil(b[2]/7);
// Add year if not already present
if (!acc[b[0]]) acc[b[0]] = {};
year = acc[b[0]];
// Add month if not already present
if (!year[b[1]]) year[b[1]] = {};
month = year[b[1]];
// Add week if not already present
if (!month[weekNum]) month[weekNum] = [];
// Add object to week
month[weekNum].push(obj);
return acc;
}, Object.create(null));
}
console.log(groupByMonthWeek(data));
如果您进行混淆,可以将其压缩到以下(但我不建议实际使用它):
var data = [
{'name' : 'example1', 'date' : '2011-01-01'},
{'name' : 'example1', 'date' : '2011-01-02'},
{'name' : 'example1', 'date' : '2011-02-02'},
{'name' : 'example1', 'date' : '2011-02-15'},
{'name' : 'example1', 'date' : '2011-02-17'},
{'name' : 'example1', 'date' : '2012-01-01'},
{'name' : 'example1', 'date' : '2012-03-03'},
];
function groupByMonthWeek(data) {
return data.reduce((acc, obj) => {
var [y, m, d] = obj.date.split(/\D/);
[y, m, '0'+Math.ceil(d/7)].reduce((a,v,i) => a[v] || (a[v] = i < 2 ? {} : []), acc).push(obj);
return acc;
}, Object.create(null));
}
console.log(groupByMonthWeek(data));
答案 2 :(得分:0)
function group(arr) {
return arr.reduce((r, o) => {
var p = o.date.split("-"); // get the parts: year, month and day
var week = Math.floor(p.pop() / 7) + 1; // calculate the week number (Math.floor(day / 7) + 1) and remove day from the parts array (p.pop())
var month = p.reduce((o, p) => o[p] = o[p] || {}, r); // get the month object (first, get the year object (if not create one), then get the month object (if not create one)
if(month[week]) month[week].push(o); // if there is an array for this week in the month object, then push this object o into that array
else month[week] = [o]; // otherwise create a new array for this week that initially contains the object o
return r;
}, {});
}
let array = [{"name":"example1","date":"2011-01-01"},{"name":"example1","date":"2011-01-02"},{"name":"example1","date":"2011-02-02"},{"name":"example1","date":"2011-02-15"},{"name":"example1","date":"2011-02-17"},{"name":"example1","date":"2012-01-01"},{"name":"example1","date":"2012-03-03"}];
console.log(group(array));
&#13;
如果您希望周数采用此格式"01", "02", ...
而非"1"; "2", ...
,请更改此行:
var week = Math.floor(p.pop() / 7) + 1;
到此:
var week = "0" + Math.floor(p.pop() / 7) + 1;
答案 3 :(得分:0)
使用lodash是可行的方法。
var myArray = [
{'name' : 'example1', 'date' : '2011-01-01'},
{'name' : 'example1', 'date' : '2011-01-02'},
{'name' : 'example1', 'date' : '2011-02-02'},
{'name' : 'example1', 'date' : '2011-02-15'},
{'name' : 'example1', 'date' : '2011-02-17'},
{'name' : 'example1', 'date' : '2012-01-01'},
{'name' : 'example1', 'date' : '2012-03-03'},
];
var orderedByMonths = _.groupBy(myArray, function(element) {
return element.date.substring(0,7);
});
var orderedByYears = _.groupBy(orderedByMonths, function(month) {
return month[0].date.substring(0,4);
});
console.log(orderedByYears);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;