如何按月对数组进行分组 - javascript

时间:2021-06-24 07:00:40

标签: javascript arrays grouping

我必须使用键名按月份对数组进行分组。

这是我的数组和预期结果数组。

请帮忙。

var data = [
        { 
          _id: "59d34fabe0a967636c7642f2", 
          date: "2019-10-20T18:30:00.000Z", 
        }, 
        { 
          _id: "59d34fab9d1a05ca06ef9775", 
          date: "2019-12-20T18:30:00.000Z", 
        }, 
        { 
          _id: "59d34fab4d49dc45357ab3a5", 
          date: "2019-12-25T18:30:00.000Z", 
        }, 
        { 
          _id: "59d34fab5aa903089e1f9a44", 
          date: "2019-11-24T18:30:00.000Z", 
        }
      ]

预期结果:

var result= [
        {
          "2019-10-01" :
          [
            {
              _id: "59d34fabe0a967636c7642f2", 
              date: "2019-10-20T18:30:00.000Z", 
            },
          ] 
        },
        {
          "2019-11-01" :
          [
            { 
              _id: "59d34fab5aa903089e1f9a44", 
              date: "2019-11-24T18:30:00.000Z", 
            }
          ] 
        },
        {
          "2019-12-01" :
          [
            { 
              _id: "59d34fab9d1a05ca06ef9775", 
              date: "2019-12-20T18:30:00.000Z", 
            }, 
            { 
              _id: "59d34fab4d49dc45357ab3a5", 
              date: "2019-12-25T18:30:00.000Z", 
            }
          ] 
        },
      ]

更新 enter image description here ………………………………………………………………………………………………………………………………………………………… ………………………………………………………………………………………………………………………………………………………… ...

3 个答案:

答案 0 :(得分:2)

类似的东西?

const data = [ { _id: "59d34fabe0a967636c7642f2", date: "2019-10-20T18:30:00.000Z", }, { _id: "59d34fab9d1a05ca06ef9775", date: "2019-12-20T18:30:00.000Z", }, { _id: "59d34fab4d49dc45357ab3a5", date: "2019-12-25T18:30:00.000Z", }, { _id: "59d34fab5aa903089e1f9a44", date: "2019-11-24T18:30:00.000Z", } ];


const sortedObj = {};
data.forEach(e => {                    // loop over all elements
  const k = e.date.slice(0, 7);        // key in YYYY-MM (e.g. 2019-10)
  const fk = `${k}-01`;                // key with appended '-01'   
  sortedObj[fk] = sortedObj[fk] || []; // create new entry if no value for key exists
  sortedObj[fk].push(e);               // add key to existing list
});

const sortedArr = Object.entries(sortedObj).sort((a,b) => new Date(a[0]) - new Date(b[0]));

console.log(sortedArr);
.as-console-wrapper { max-height: 100% !important; top: 0; }

或者作为单线:

const data = [ { _id: "59d34fabe0a967636c7642f2", date: "2019-10-20T18:30:00.000Z", }, { _id: "59d34fab9d1a05ca06ef9775", date: "2019-12-20T18:30:00.000Z", }, { _id: "59d34fab4d49dc45357ab3a5", date: "2019-12-25T18:30:00.000Z", }, { _id: "59d34fab5aa903089e1f9a44", date: "2019-11-24T18:30:00.000Z", } ];

const sorted = (a = {}, data.forEach(e => { b = e.date.slice(0, 7); c = `${b}-01`; a[c] = a[c] || []; a[c].push(e); }), a = Object.entries(a).sort((a,b) => new Date(a[0]) - new Date(b[0])), a);
console.log(sorted);

答案 1 :(得分:1)

一个简单的 reduce 循环就可以解决问题。整个玉米粉蒸肉将被 Object.fromEntries() 格式化,它本质上采用我们完成的数组并将其转换为具有键/值对的对象数组。内部循环包含在 Object.entries 中,它允许我们像数组一样迭代对象。排序是日期属性的 localeCompare

const months = Object.fromEntries( // convert our final result back into key/values pairs
  Object.entries(data.reduce((b, a) => {  // convert to an iterable array
  let m = a.date.split("T")[0].substr(0, 7) + "-01"; // set up date property for grouping
  if (b.hasOwnProperty(m)) b[m].push(a); else b[m] = [a];  // create or add to accumulating group
  return b; }, {}))
  .sort((a,b) => a[0].localeCompare(b[0]))) // sort by date property

var data = [{
    _id: "59d34fabe0a967636c7642f2",
    date: "2019-10-20T18:30:00.000Z",
  },
  {
    _id: "59d34fab9d1a05ca06ef9775",
    date: "2019-12-20T18:30:00.000Z",
  },
  {
    _id: "59d34fab4d49dc45357ab3a5",
    date: "2019-12-25T18:30:00.000Z",
  },
  {
    _id: "59d34fab5aa903089e1f9a44",
    date: "2019-11-24T18:30:00.000Z",
  }
]
//Object.fromEntries(
const months = Object.entries(data.reduce((b, a) => {
  let m = a.date.split("T")[0].substr(0, 7) + "-01";
  if (b.hasOwnProperty(m)) b[m].push(a); else b[m] = [a];
  return b; }, {}))
  .sort((a,b) => a[0].localeCompare(b[0]))
  .map(e => ({[e[0]]:e[1]}));
console.log(months)

答案 2 :(得分:0)

您可以使用 array#reduce 在对象累加器中根据月份和年份对数据进行分组。然后使用 Object.values() 提取所有值。然后,根据日期键对结果进行排序。

const data = [{ _id: "59d34fabe0a967636c7642f2", date: "2019-10-20T18:30:00.000Z", }, { _id: "59d34fab9d1a05ca06ef9775", date: "2019-12-20T18:30:00.000Z", }, { _id: "59d34fab4d49dc45357ab3a5", date: "2019-12-25T18:30:00.000Z", }, { _id: "59d34fab5aa903089e1f9a44", date: "2019-11-24T18:30:00.000Z", } ],
    grouped = Object.values(data.reduce((r, o) => {
      const date = `${o.date.substr(0,7)}-01`;
      r[date] ||= {[date]: []};
      r[date][date].push(o);
      return r;
    }, []))
    .sort((a,b) => Object.keys(a)[0].localeCompare(Object.keys(b)[0]));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }