如何按月和年对日期数组进行分组

时间:2021-01-12 05:13:45

标签: javascript arrays

嗨,我有一个日期对象数组

  "["2021-01-05T06:30:00.000Z","2021-01-06T06:30:00.000Z",
    "2021-01-20T06:30:00.000Z","2021-02-09T06:30:00.000Z",
    "2021-02-23T06:30:00.000Z","2021-02-16T06:30:00.000Z",
    "2020-12-08T06:30:00.000Z","2020-12-15T06:30:00.000Z",
    "2020-12-02T06:30:00.000Z","2020-12-09T06:30:00.000Z",
    "2020-12-16T06:30:00.000Z"]"

我需要格式化成这个

[
  {
    "month": "12",
    "year": "2020",
    "dates": [1,14,25]
  },
  {
    "month": "10",
    "year": "2020",
    "dates": [1]
  }
]

如何格式化这样的帮助我。我已经这样做了但没有完成我一直在添加日期。我知道这不是正确的做法。请不要打扰我写的代码我知道这是垃圾。

dateArray.reduce((initial,next)=>{
   let result=[]    
   if(isSameYear(new Date(initial),new Date(next) && 
      isSameMonth(new Date(initial),new Date(next))){
         result.push({
                 month:new Date(nex).getMonth(), 
                  year: new Date(next).getFullYear 
         })
    }
})

5 个答案:

答案 0 :(得分:2)

您可以根据对象累加器中的 yearmonth 对日期进行分组。

const data = ["2021-01-05T06:30:00.000Z", "2021-01-06T06:30:00.000Z", "2021-01-20T06:30:00.000Z", "2021-02-09T06:30:00.000Z", "2021-02-23T06:30:00.000Z", "2021-02-16T06:30:00.000Z", "2020-12-08T06:30:00.000Z", "2020-12-15T06:30:00.000Z", "2020-12-02T06:30:00.000Z", "2020-12-09T06:30:00.000Z", "2020-12-16T06:30:00.000Z" ],
      result = Object.values(data.reduce((r, date) => {
        const [year, month, day] = date.substr(0,10).split('-');
        const key = `${year}_${month}`;
        r[key] = r[key] || {month, year, dates: []};
        r[key].dates.push(day);
        return r;
      },{}));
console.log(result);

答案 1 :(得分:1)

也许分两遍

const dateArray = ["2021-01-05T06:30:00.000Z", "2021-01-06T06:30:00.000Z", "2021-01-20T06:30:00.000Z", "2021-02-09T06:30:00.000Z", "2021-02-23T06:30:00.000Z", "2021-02-16T06:30:00.000Z", "2020-12-08T06:30:00.000Z", "2020-12-15T06:30:00.000Z", "2020-12-02T06:30:00.000Z", "2020-12-09T06:30:00.000Z", "2020-12-16T06:30:00.000Z"];


const mapping = dateArray.reduce((initial, next) => {
  const month = next.substring(5, 7);
  const year = next.substring(0, 4);
  const day = next.substring(8, 10);

  initial[year] = initial[year] || {};
  initial[year][month] = initial[year][month] || [];
  initial[year][month].push(parseInt(day, 10));
  return initial;
}, {});

const result = []
Object.keys(mapping).forEach(year => {
  Object.keys(mapping[year]).forEach(month => {
    result.push({
      month,
      year,
      dates: mapping[year][month]
    });
  });
});

console.log(result);

答案 2 :(得分:1)

一个简单的解决方案是使用一个对象按月和年分组,如下所示:

const data = ["2021-01-05T06:30:00.000Z","2021-01-06T06:30:00.000Z",
    "2021-01-20T06:30:00.000Z","2021-02-09T06:30:00.000Z",
    "2021-02-23T06:30:00.000Z","2021-02-16T06:30:00.000Z",
    "2020-12-08T06:30:00.000Z","2020-12-15T06:30:00.000Z",
    "2020-12-02T06:30:00.000Z","2020-12-09T06:30:00.000Z",
    "2020-12-16T06:30:00.000Z"];

function groupDates(dates) {
    const groupedDates = {};
    dates.forEach(d => {
        const dt = new Date(d);
        const date = dt.getDate();
        const year = dt.getFullYear();
        const month = dt.getMonth() + 1;
        
        const key = `${year}-${month}`;
        if (key in groupedDates) {
            groupedDates[key].dates = [...groupedDates[key].dates, date];
        } else {
            groupedDates[key] = {
                year,
                month,
                dates: [date],
            };
        }

    });

    return Object.values(groupedDates);
}

console.log(groupDates(data));

答案 3 :(得分:0)

当您对一般事物进行分组时,将它们分组为一个对象会更容易。原因是您不必在数组中搜索要追加的匹配结果,只需查找要连接的键即可。

这是一种构建对象的解决方案,按月份和年份构建的字符串键分组,然后映射该对象的值以构建您要查找的数组,方法是将字符串键拆分为它们的重要值部分。

const dates = ["2021-01-05T06:30:00.000Z","2021-01-06T06:30:00.000Z","2021-01-20T06:30:00.000Z","2021-02-09T06:30:00.000Z","2021-02-23T06:30:00.000Z","2021-02-16T06:30:00.000Z","2020-12-08T06:30:00.000Z","2020-12-15T06:30:00.000Z","2020-12-02T06:30:00.000Z","2020-12-09T06:30:00.000Z","2020-12-16T06:30:00.000Z"];

const grouped = dates.reduce((accumulator, date) => {
  const parsed = new Date(date);
  const year = parsed.getFullYear();
  const month = parsed.getMonth();
  const groupKey = `${month},${year}`;
  accumulator[groupKey] = accumulator[groupKey] || {dates: []};
  accumulator[groupKey].dates.push(parsed.getDay());
  return accumulator;
}, {});

const result = Object.entries(grouped).map(([key, dates]) => {
  const parts = key.split(',');
  return {
    month: parts[0],
    year: parts[1],
    dates: dates
  };
});

console.log(result);

答案 4 :(得分:0)

这是一个不使用任何库的纯 javascript 解决方案。它基于一个简单的 O(n^2) 运行时。但是如果你喜欢用一些库来做二分查找,你可以把它减少到 O(nlogn)。

诀窍是把这个任务变成更小的任务,就像我用函数 getMonthYear(将字符串转换为对象)、比较和添加日期一样:

data = ["2021-01-05T06:30:00.000Z","2021-01-06T06:30:00.000Z","2021-01-20T06:30:00.000Z","2021-02-09T06:30:00.000Z","2021-02-23T06:30:00.000Z","2021-02-16T06:30:00.000Z","2020-12-08T06:30:00.000Z","2020-12-15T06:30:00.000Z","2020-12-02T06:30:00.000Z","2020-12-09T06:30:00.000Z","2020-12-16T06:30:00.000Z"];

function categorize(data) {

    // 2021-01-05T06:30:00.000Z => {month:"01", year:"2021", date:"05"}
  function getMonthYear(str) {
    var datePart = str.toString().trim().split("T")[0];
    var datePartArr = datePart.split("-");
    return {month:datePartArr[1], year:datePartArr[0], date:datePartArr[2]};
  }
  // testing
  //var ans = getMonthYear("2021-01-06T06:30:00.000Z");
  //console.log(ans);
  
  // comparing two items to see if they have the same year and month
  function compare(item1, item2) {
    return (item1.month == item2.month) && (item1.year == item2.year);
  }
  // testing
  //var ans = compare({month:"04", year:"2021"}, {month:"03", year:"2021"});
  //console.log(ans);
  
  // adding a date to the list of dates
  function addDate(dateList, dateNumber) {
 
    for(var i in dateList) {
        if (dateList[i] == dateNumber) return;
    }

        dateList.push(dateNumber);
    
  }
  // testing 
  /*var ans = [2,4];
  addDate(ans, 4);
  console.log(ans);*/
  
  // Now lets build the answer by looping over
  // --------------------------------------------
  var list = []; // the final answer list
  
  data.forEach(function(str){
    var item = getMonthYear(str);
    var itemMatched = false;
    // now lopping over the list to see if it has any match
    
    for(var i in list) {
        if (compare(item, list[i])) {   // matched found
        itemMatched = true;
        addDate(list[i].date, item.date);
        break;
      }
    }
    
    // item had no match, add it as a new item to list
    if (!itemMatched) { 
        list.push({
        month: item.month,
        year: item.year,
        date: [item.date]
      });
    }    
  });
  
  return list;
  
}

var ans = categorize(data); 
console.log(ans);

这是指向 jsfiddle

的链接