按周将对象数组拆分为组

时间:2018-02-14 13:17:40

标签: javascript arrays

我有一个包含这样的数据的对象数组

[{
  date: "01-01-2017 00:00:00",
  dataField1: "",
  dataField2: ""
},
{
  date: "01-02-2017 00:00:00",
  dataField1: "",
  dataField2: ""
},
{
  date: "01-15-2017 00:00:00",
  dataField1: "",
  dataField2: ""
},
{
  date: "01-16-2017 00:00:00",
  dataField1: "",
  dataField2: ""
},
{
  date: "01-15-2018 00:00:00",
  dataField1: "",
  dataField2: ""
},
{
  date: "01-16-2018 00:00:00",
  dataField1: "",
  dataField2: ""
}]]

UPD:需要按年份和月份排序,而不仅仅是月份。 我需要将它拆分为一个数组数组,其中对象按周和年分组。 像这样的东西:

[
  [{
     date: "01-01-2017 00:00:00",
     dataField1: "",
     dataField2: ""
   },
   {
     date: "01-02-2017 00:00:00",
     dataField1: "",
     dataField2: ""
   }
  ],
  [{
     date: "01-15-2017 00:00:00",
     dataField1: "",
     dataField2: ""
   },
   {
     date: "01-16-2017 00:00:00",
     dataField1: "",
     dataField2: ""
   }],
   [
    {
       date: "01-15-2018 00:00:00",
       dataField1: "",
       dataField2: ""
    },
    {
       date: "01-16-2018 00:00:00",
       dataField1: "",
       dataField2: ""
    }
   ]
]

是否有一种性能良好的简单方法,可以使用 javascript 进行排序?

2 个答案:

答案 0 :(得分:3)

如果您考虑使用momentjs之类的内容,则可以使用格式化功能。这样,您实际上可以按列出here列出的任何可用日期格式标记进行分组。

function datesGroupByComponent(dates, token) {
  return dates.reduce(function(val, obj) {
    let comp = moment(obj['date'], 'MM/DD/YYYY').format(token);
    (val[comp] = val[comp] || []).push(obj);
    return val;
  }, {});
}

const dates = [
  { date: "01-01-2017 00:00:00" },
  { date: "01-02-2017 00:00:00" },
  { date: "01-15-2017 00:00:00" },
  { date: "01-16-2017 00:00:00" }
];

/* https://momentjs.com/docs/#/displaying/format */

console.log('D', datesGroupByComponent(dates, 'D')); // Day of Month
console.log('w', datesGroupByComponent(dates, 'w')); // Week of Year
console.log('W', datesGroupByComponent(dates, 'W')); // Week of Year (ISO)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

答案 1 :(得分:1)

我碰巧有一些code on hand来确定ISO-8601 Week number

从那里只需要将日期字符串拆分为可以传递给本地Date constructor的可用部分,然后将reduce对象分解为具有键的内容,这样我们就可以将日期放入正确的组,最后,按照您的要求,使用Object.values()删除密钥以使其成为一个数组。

var dates = [{
    date: "01-01-2017 00:00:00",
    dataField1: "",
    dataField2: ""
  },
  {
    date: "01-02-2017 00:00:00",
    dataField1: "",
    dataField2: ""
  },
  {
    date: "01-15-2017 00:00:00",
    dataField1: "",
    dataField2: ""
  },
  {
    date: "01-16-2017 00:00:00",
    dataField1: "",
    dataField2: ""
  }
];

var group = Object.values(dates.reduce((acc, val) => {
  var dateparts = val.date.split(/ |-|:/g);
  var date = new Date(dateparts[2], dateparts[0] - 1, dateparts[1], dateparts[3], dateparts[4], dateparts[5]);
  var weekNo = getISO8601WeekNo(date);
  if (!acc[weekNo]) acc[weekNo] = [];
  acc[weekNo].push(val);
  return acc;
}, {}));

console.log(group);

function getISO8601WeekNo(date) {
  var startDate = new Date(date.getFullYear(), 0);
  var endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
  while (endDate.getDay() < 6) endDate.setDate(endDate.getDate() + 1);
  endDate = endDate.getTime();
  var weekNo = 0;
  while (startDate.getTime() < endDate) {
    if (startDate.getDay() == 4) weekNo++;
    startDate.setDate(startDate.getDate() + 1);
  }
  return weekNo;
}

相关问题