javascript 如何使用数据数组按月分组

vhipe2zx  于 2023-01-19  发布在  Java
关注(0)|答案(3)|浏览(143)

我的数组是这样的:

const myArray = [{
    date: "2017-01-01",
    Name: "test1"
  },
  {
    date: "2017-01-02",
    Name: "test2"
  },
  {
    date: "2017-02-04",
    Name: "test3"
  },
  {
    date: "2017-02-05",
    Name: "test3"
  }
]

我想将此转换为:

const myArray = [{
    group: "Jan",
    data: [{
        date: "2017-01-01",
        Name: "test1"
      },
      {
        date: "2017-01-02",
        Name: "test2"
      }
    ]
  },
  {
    group: "Feb",
    data: [{
        date: "2017-02-04",
        Name: "test3"
      },
      {
        date: "2017-02-05",
        Name: "test3"
      }
    ]
  }
]
daolsyd0

daolsyd01#

假设myArray中的date总是yyyy-MM-dd,那么我的解决方案应该工作得很好。

const myArray = [{
    date: "2017-01-01",
    Name: "test1"
  },
  {
    date: "2017-01-02",
    Name: "test2"
  },
  {
    date: "2017-02-04",
    Name: "test3"
  },
  {
    date: "2017-02-05",
    Name: "test3"
  }
]

const result = myArray.reduce((p,c)=>{
    const monthOfData = new Date(c.date).toLocaleString('default', { month: 'short' });
    const found = p.findIndex(p => p.group === monthOfData);
    if(found !==-1){
        p[found].data.push(c);
    } else {
        p.push({
            group: monthOfData,
            data:[c]
        })
    }

    return p;
}, []);

console.log(result);

或者,@danh的建议是,使用一个对象构建索引,然后进行第二次传递以重新形成所需的输出......

const myArray = [
  {date: "2017-01-01", Name: "test1"}, 
  {date: "2017-01-02", Name: "test2"},
  {date: "2017-02-04", Name: "test3"},
  {date: "2017-02-05", Name: "test3"} ]

// reduce into an object. keys are unique and O(1) lookup
const byDate = myArray.reduce((p, c) => {
  const monthOfData = new Date(c.date).toLocaleString('default', { month: 'short' });
  p[monthOfData] ??= []
  p[monthOfData].push(c)
  return p;
}, {});

// re-form to match the output
const result = Object.keys(byDate).map(d => {
  return { group: d, data: byDate[d] } 
})

console.log(result)

,用于按年和月分组。

const myArray = [
    { date: "2021-11-01", Name: "example1" },
    { date: "2021-12-01", Name: "example2" },
    { date: "2022-02-01", Name: "example3" },
    { date: "2022-02-02", Name: "example4" },
    { date: "2023-05-22", Name: "example5" }
]

const result = myArray.reduce((p, c) => {
    const [monthOfData, yearOfData] = new Date(c.date).toLocaleString("default", { month: "short", year: "numeric" }).split(" ");
    p[yearOfData] ??= {};
    p[yearOfData][monthOfData] ??= [];
    p[yearOfData][monthOfData].push(c);

    return p
}, {});

console.log(result);
wswtfjt7

wswtfjt72#

您可以使用Object.entries()Array#reduceArray#map方法,如下所示 *:

const 
    myArray = [ { date: "2017-01-01", Name: "test1" }, { date: "2017-01-02", Name: "test2" }, { date: "2017-02-04", Name: "test3" }, { date: "2017-02-05", Name: "test3" } ],
    month = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],

    outArr = Object.entries(
      myArray.reduce(
        (acc,{date,Name,group = month[+date.split('-')[1] - 1]}) =>
        ({ ...acc, [group]:[...(acc[group] || []),{date,Name}] }), {}
      )
    )
    .map(([group,data]) => ({group,data}));

console.log( outArr );
      • 感谢@Layhout告诉我如何计算给定日期的短月份名。每天我都能学到新东西! *
    • 注**

我想知道为什么new Date( 2017 - 01 - 01 ).toLocaleString('default',{month:'short'})认为日期是Sat Dec 31, 2016,因此给出Dec而不是Jan,可能是Date对象有bug;如果日期的格式是mm-dd-yyyy,它可以正常工作,但是如果是yyyy-mm-dd,对象总是减去一天。

    • 或者...**

使用mm-dd-yyyy格式将按预期工作至少在此为默认日期格式

const 
    myArray = [ { date: "2017-01-01", Name: "test1" }, { date: "2017-01-02", Name: "test2" }, { date: "2017-02-04", Name: "test3" }, { date: "2017-02-05", Name: "test3" } ],

    outArr = Object.entries(
      myArray.reduce(
        (acc,{date,Name,d = date.split('-'),group = new Date([d[1],d[2],d[0]].join('-')).toLocaleString('default',{month:'short'})}) =>
        ({ ...acc, [group]:[...(acc[group] || []),{date,Name}] }), {}
      )
    )
    .map(([group,data]) => ({group,data}));

console.log( outArr );
9lowa7mx

9lowa7mx3#

希望您能从下面的示例代码中得到帮助。
这里TestA应该是一个类,其内容日期和名称属性。

HashMap<String, List<TestA>> map = new HashMap<>();
        for (TestA testA: myArray){
            String month = monthName(testA.getDate());
            if(!map.containsKey(month)){
                map.put(month, new ArrayList<>());
            }
            map.get(month).add(testA);
        }

public String monthName(String date){
        try {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
            calendar.setTime(sdf.parse(date));
            return new DateFormatSymbols().getMonths()[calendar.get(Calendar.MONTH)];

        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

谢谢

相关问题