首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何按日期和值筛选对象数组

如何按日期和值筛选对象数组
EN

Stack Overflow用户
提问于 2022-01-10 17:41:51
回答 3查看 497关注 0票数 -2

我得到的是一个包含类别、日期和值的对象数组,如下所示

代码语言:javascript
复制
const records = 
  [ { category: 'Cat 1', date: '2020-11-03', value: '300.00' } 
  , { category: 'Cat 2', date: '2020-11-03', value: '350.00' } 
  , { category: 'Cat 3', date: '2020-11-03', value:  '50.00' } 
  , { category: 'Cat 1', date: '2020-11-13', value: '200.00' } 
  , { category: 'Cat 1', date: '2020-12-23', value: '100.00' } 
  , { category: 'Cat 2', date: '2020-11-23', value: '350.00' } 
  , { category: 'Cat 3', date: '2020-11-15', value:  '50.00' } 
  , { category: 'Cat 3', date: '2021-01-15', value:  '50.00' } 
  ]

我想得到的是包含每个类别、月份和每月总价值的新数组,如下所示:

代码语言:javascript
复制
const newRecords = 
  [ { category: 'Cat 1'
    , totalPerMonth: 
      [ { month: '2020-11', totalMonthlyValue: '500.00' } 
      , { month: '2020-12', totalMonthlyValue: '100.00' } 
    ] } 
  , { category: 'Cat 2'
    , totalPerMonth: 
      [ { month: '2020-11', totalMonthlyValue: '700.00' } 
    ] } 
  , { category: 'Cat 3'
    , totalPerMonth: 
      [ { month: '2020-11', totalMonthlyValue: '100.00' } 
      , { month: '2021-01', totalMonthlyValue:  '50.00' } 
  ] } ]
EN

回答 3

Stack Overflow用户

发布于 2022-01-10 18:58:30

您可以先按类别将数据分组,然后再按日期分组。然后,您需要对所有值进行求和,并像定义的那样返回结构。这里有一个例子,它正是这样做的。

代码语言:javascript
复制
const records = [
  {category: 'Cat 1', date: '2020-11-03', value: '300.00'},
  {category: 'Cat 2', date: '2020-11-03', value: '350.00'},
  {category: 'Cat 3', date: '2020-11-03', value: '50.00'},
  {category: 'Cat 1', date: '2020-11-13', value: '200.00'},
  {category: 'Cat 1', date: '2020-12-23', value: '100.00'},
  {category: 'Cat 2', date: '2020-11-23', value: '350.00'},
  {category: 'Cat 3', date: '2020-11-15', value: '50.00'},
  {category: 'Cat 3', date: '2021-01-15', value: '50.00'}
];

// first you need to group it by category, you can do that by
// assigning a group indicator as key to an object and add an
// array as value containing all values. you can also use lodash's
// groupBy for grouping values.
const groupedRecords = {};
records.forEach(record => {
  if (groupedRecords[record.category] === undefined) {
    groupedRecords[record.category] = [];
  }
  groupedRecords[record.category].push(record);
});

// then, you need to go through each category group and group all
// records again by date. you can use the same pattern as above.
const result = Object.entries(groupedRecords).map(([category, recordsOfOneCategory]) => {
  const groupedDates = {};
  recordsOfOneCategory.forEach(record => {
    // this regex extracts the date per month. it's probably better 
    // to use a date library for this part
    const month = record.date.match(/^(\d{4}-\d{2})/)[1];
    if (groupedDates[month] === undefined) {
      groupedDates[month] = [];
    }
    groupedDates[month].push(record);
  });
  
  // now you have for each category group a group of dates with
  // records in it. you now need to make a sum for each group of
  // dates. you can do this by mapping the values into an array of
  // only values and then sum them up using reduce.
  const totalPerMonth = Object.entries(groupedDates).map(([month, items]) => ({
    month,
    totalMonthlyValue: items.map(item => parseFloat(item.value)).reduce((a,b) => a + b).toFixed(2)
  }));
  
  return { category, totalPerMonth };
});

console.log(result);

票数 1
EN

Stack Overflow用户

发布于 2022-01-10 22:10:40

这边请

代码语言:javascript
复制
const records = 
  [ { category: 'Cat 1', date: '2020-11-03', value: '300.00' } 
  , { category: 'Cat 2', date: '2020-11-03', value: '350.00' } 
  , { category: 'Cat 3', date: '2020-11-03', value:  '50.00' } 
  , { category: 'Cat 1', date: '2020-11-13', value: '200.00' } 
  , { category: 'Cat 1', date: '2020-12-23', value: '100.00' } 
  , { category: 'Cat 2', date: '2020-11-23', value: '350.00' } 
  , { category: 'Cat 3', date: '2020-11-15', value:  '50.00' } 
  , { category: 'Cat 3', date: '2021-01-15', value:  '50.00' } 
  ]

const result =
  Object.values(
  records.reduce((r,{category,date,value}) =>
    {
    let Ym  = date.substring(0,7)
    if (!r[category])          r[category] = { category, sum : {} }
    if (!r[category].sum[Ym])  r[category].sum[Ym] = 0
    r[category].sum[Ym] += Number(value)
    return r
    },{}
  )).map(({category,sum}) =>
    {
    let totalPerMonth = Object.entries(sum).map(([month,sum])=>({month,totalMonthlyValue:sum.toFixed(2)}))
    return { category,totalPerMonth }
    },{})

console.log ( result  )
代码语言:javascript
复制
.as-console-wrapper {max-height: 100%!important;top:0 }

票数 1
EN

Stack Overflow用户

发布于 2022-01-10 19:27:21

可以使用对象中的array#reduce根据类别和月份进行分组。然后使用Object.values()array#map从该对象提取所有值。

代码语言:javascript
复制
const records = [ { category: 'Cat 1', date: '2020-11-03', value: '300.00' } , { category: 'Cat 2', date: '2020-11-03', value: '350.00' } , { category: 'Cat 3', date: '2020-11-03', value: '50.00' } , { category: 'Cat 1', date: '2020-11-13', value: '200.00' } , { category: 'Cat 1', date: '2020-12-23', value: '100.00' } , { category: 'Cat 2', date: '2020-11-23', value: '350.00' } , { category: 'Cat 3', date: '2020-11-15', value: '50.00' } , { category: 'Cat 3', date: '2021-01-15', value: '50.00' } ],
      result = records.reduce((r, {category, date, value}) => {
        const month = date.substring(0, 7);
        r[category] ??= {category};
        r[category][month] ??= {month, total: 0};
        r[category][month].total += +value;
        return r;
      },{}),
      newRecords = Object
        .values(result)
        .map( ({category, ...rest}) => 
          ({  category, 
              totalPerMonth: Object.values(rest).map(({ month, total }) => 
                              ({ month, totalMonthlyValue: total.toFixed(2) }) 
                              ) }) );
console.log(newRecords);
代码语言:javascript
复制
.as-console-wrapper { max-height: 100% !important; top: 0; }

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70656715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档