【问题标题】:How to restructure and map an array to fit into a specified data structure in React如何重构和映射数组以适应 React 中的指定数据结构
【发布时间】:2021-12-05 01:31:36
【问题描述】:

我正在使用 reaviz 是 React 的图表工具。我正在创建一个习惯跟踪器应用程序,并希望在一系列条形图上直观地显示用户输入最后一周的数据。我的数据库中的数据结构如下:

habits = [
 { 
   habit: "Cook Dinner",
   inputs: [
     {
      input: 'Success',
      date: 'Oct 5th 21'
     },
     {
      input: 'Fail',
      date: 'Oct 6th 21'
     },
     {
      input: 'Skip',
      date: 'Oct 7th 21'
     }]
  },
  { 
   habit: "Clean House",
   inputs: [
     {
      input: 'Fail',
      date: 'Oct 5th 21'
     },
     {
      input: 'Fail',
      date: 'Oct 6th 21'
     },
     {
      input: 'Fail',
      date: 'Oct 7th 21'
    }]
  },
  { 
   habit: "Cook Dinner",
     inputs: [
     {
      input: 'Success',
      date: 'Oct 5th 21'
     },
     {
      input: 'Fail',
      date: 'Oct 6th 21'
     },
     {
      input: 'Skip',
      date: 'Oct 7th 21'
     }]
   }]

所以现在我想找到一种方法将我的数据映射到图表所需的数据结构,例如上述数据的输出将是这样的。我需要计算当天有多少输入是成功、失败或跳过:

habitsMappedData = [
     {
    key: 'Oct 5th 21',
    data: [
      {
        key: 'Success',
        data: 2
      },
      {
        key: 'Fail',
        data: 1
      },
      {
        key: 'Skip',
        data: 0
      }
    ]
  },  {
    key: 'Oct 6th 21',
    data: [
      {
        key: 'Sucess',
        data: 0
      },
      {
        key: 'Fail',
        data: 3
      },
      {
        key: 'Skip',
        data: 0
      }
    ]
  },  {
    key: 'Oct 7th 21',
    data: [
      {
        key: 'Success',
        data: 0
      },
      {
        key: 'Fail',
        data: 1
      },
      {
        key: 'Skip',
        data: 2
      }
    ]
  },
]

非常感谢您浏览此内容。如果需要任何澄清,请告诉我。

【问题讨论】:

    标签: javascript arrays reactjs filter mapping


    【解决方案1】:

    这实际上只是按日期的“分组”操作,但由于嵌套数组,它涉及的更多一些。

    下面的 sn-p 使用reduce() 调用以使用date 作为分组属性并使用input 作为辅助属性求和到一个对象中。要将结果对象转换回嵌套对象数组,它在返回对象的Object.entries() 上调用Array.from(),并使用作为second parameter of Array.from() 提供的map 映射keydata 属性。嵌套的data 对象是使用最终的map() 调用生成的。

    const habits = [ { habit: 'Cook Dinner', inputs: [ { input: 'Success', date: 'Oct 5th 21', }, { input: 'Fail', date: 'Oct 6th 21', }, { input: 'Skip', date: 'Oct 7th 21', }, ], }, { habit: 'Clean House', inputs: [ { input: 'Fail', date: 'Oct 5th 21', }, { input: 'Fail', date: 'Oct 6th 21', }, { input: 'Fail', date: 'Oct 7th 21', }, ], }, { habit: 'Cook Dinner', inputs: [ { input: 'Success', date: 'Oct 5th 21', }, { input: 'Fail', date: 'Oct 6th 21', }, { input: 'Skip', date: 'Oct 7th 21', }, ], }, ];
    
    const habitsMappedData = Array.from(
      Object.entries(
        habits.reduce((a, { inputs }) => {
          for (const { date, input } of inputs) {
            (a[date] ??= { Success: 0, Fail: 0, Skip: 0 })[input] += 1;
          }
    
          return a;
        }, {})
      ),
      ([key, _data]) => ({
        key,
        data: Object.entries(_data).map(([key, data]) => ({ key, data })),
      })
    );
    
    console.log(habitsMappedData);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    注意:以上依赖于logical nullish assignment operator (??=),如果需要兼容性,可以用OR 短路替换。

    for (const { date, input } of inputs) {
      (a[date] || (a[date] = { Success: 0, Fail: 0, Skip: 0 }))[input] += 1;
    }
    

    或在if 中明确写出

    for (const { date, input } of inputs) {
      if (a[date] === undefined) {
        a[date] = { Success: 0, Fail: 0, Skip: 0 };
      }
      a[date][input] += 1;
    }
    

    【讨论】:

    • 完美运行。你我的朋友真了不起。我从中学到了很多。非常感谢您抽出时间帮助我解决这个问题。
    猜你喜欢
    • 2017-07-15
    • 1970-01-01
    • 2013-08-07
    • 2012-11-26
    • 2015-06-26
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 2016-10-26
    相关资源
    最近更新 更多