[英]Javascript - Array of objects group by year, month and date
我正在嘗試按日期月份和星期對一組對象進行排序
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)
。
我設法按年,月,年和周對數據進行排序,但是我無法弄清楚如何同時對這三個數據進行處理。
謝謝你的幫助
您可以將for..of
循環, String.prototype.match()
與RegExp
/\\d+/
以獲取YYYY
和"date"
屬性值的MM
部分; Array.prototype.filter()
通過將YYYY
與"-"
和MM
串聯,將輸入數組中對象的YYYY-MM
與for..of
循環中的當前對象進行for..of
。
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/
從您的問題中確實不清楚您要做什么。 ISO周數基於年份而不是月份,例如2011-01-01落在2010年的最后一周而不是2011年的第一周。您真的不能將按月分組和ISO周數相結合,大約10周每年將從一個月開始,到另一個月結束。
如果您將一天的“一個月中的一周”的概念只是Math.ceil(day number / 7)
,則可以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));
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));
如果您希望星期數采用"01", "02", ...
而不是"1"; "2", ...
格式"1"; "2", ...
"1"; "2", ...
,然后更改此行:
var week = Math.floor(p.pop() / 7) + 1;
對此:
var week = "0" + Math.floor(p.pop() / 7) + 1;
使用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);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.