【问题标题】:Iterate through list of objects and transform into an object with nested list of objects遍历对象列表并转换为具有嵌套对象列表的对象
【发布时间】:2021-07-25 22:36:29
【问题描述】:

假设我有一个生成对象列表的 API:

const data = [
    {
        "get_study_name": "INFRONT-3",
        "visit_status": "Completed",
        "get_year": 2021,
        "get_month": 7
    },
    {
        "get_study_name": "EMBARK",
        "visit_status": "Completed",
        "get_year": 2021,
        "get_month": 7
    },
    {
        "get_study_name": "INFRONT-3",
        "visit_status": "Completed",
        "get_year": 2020,
        "get_month": 6
    }
]

是否可以通过它进行迭代或映射并产生这样的结果?

newData: {
    2021: [
       {
          name: 'INFRONT-3', 'EMBARK' //string concatenation of get_study_name
          data: [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0], //array of months (index +1), and count occurence
          fill: 'start' //inject this on each object
        }
          ],
    2020: [
       {
          name: 'INFRONT-3'
          data: [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
          fill: 'start'
        }
          ],
}

我非常感谢任何提示。我已经被困了 3 天,我能做的最多的是获得独特的岁月。

【问题讨论】:

  • 你试过使用reduce吗?如果是这样,你能分享一下吗?

标签: javascript arrays json javascript-objects


【解决方案1】:

您在示例中的评论

//get_study_name的加入字符串

不清楚,它没有将字符串显示为已连接,实际上是换行/使对象无效。 也不清楚在什么条件下 year 数组应该包含多个对象。

const data = [
        {
            "get_study_name": "INFRONT-3",
            "visit_status": "Completed",
            "get_year": 2021,
            "get_month": 7
        },
        {
            "get_study_name": "EMBARK",
            "visit_status": "Completed",
            "get_year": 2021,
            "get_month": 7
        },
        {
            "get_study_name": "INFRONT-3",
            "visit_status": "Completed",
            "get_year": 2020,
            "get_month": 6
        }
    ];

const newData = {};
for (let i = 0; i < data.length; i++)
{
  const d = data[i],
        obj = (newData[d.get_year] || [{name:'',data:Array(12).fill(0),fill:"start"}])[0];

  obj.name += (obj.name && ", ") + d.get_study_name; // add name
  obj.data[d.get_month-1]++; // increase month count
  newData[d.get_year] = [obj];
}
console.log(newData);

【讨论】:

  • 谢谢。我现在已经编辑了评论。它应该是串联,而不是连接。
【解决方案2】:
const newData = {}
data.forEach(d => {
  if (newData[d.get_year]) {
    const datum = newData[d.get_year];
    datum.name += `,${d.get_study_name}`;
    datum.data[d.get_month + 1]++;
  } else {
      newData[d.get_year] = {
          name: d.get_study_name,
          data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          fill: 'start'
      }
      newData[d.get_year].data[d.get_moth+1]++;
  }
});

【讨论】:

    【解决方案3】:

    这是一种使用 reduce 和 map 组合的方法。

    const data = [{
        "get_study_name": "INFRONT-3",
        "visit_status": "Completed",
        "get_year": 2021,
        "get_month": 7
      },
      {
        "get_study_name": "EMBARK",
        "visit_status": "Completed",
        "get_year": 2021,
        "get_month": 7
      },
      {
        "get_study_name": "INFRONT-3",
        "visit_status": "Completed",
        "get_year": 2020,
        "get_month": 6
      }
    ]
    
    let obj = Object.fromEntries(Object.entries(data.reduce((acc, a) => {
      if (!acc.hasOwnProperty(a.get_year)) acc[a.get_year] = [];
      let b = acc[a.get_year]
      let i = b.findIndex(e => e.get_month = a.get_month)
      if (i > -1) {
        b[i].name.push(a.get_study_name);
        b[i].data[a.get_month]++
      } else {
        let cal = Array(12).fill(0);
        cal[a.get_month]++
          b.push({ ...a,
            data: cal,
            name: [a.get_study_name]
          })
      }
      return acc
    }, {})).map(d => {
      d[1] = d[1].map(e => {
        delete e.get_study_name;
        delete e.get_month;
        delete e.get_year;
        delete e.visit_status;
        e.fill = 'start';
        e.name = e.name.join(', ')
        return e;
      })
      return d
    }))
    
    console.log(obj)
    /*
        
        newData: {
        2021: [
           {
              name: 'INFRONT-3', 'EMBARK' //joined string of get_study_name
              data: [0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0], //array of months (index +1), and count occurence
              fill: 'start' //inject this on each object
            }
              ],
        2020: [
           {
              name: 'INFRONT-3'
              data: [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
              fill: 'start'
            }
              ],
    }
    */

    【讨论】:

      猜你喜欢
      • 2020-07-14
      • 2018-05-20
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 1970-01-01
      • 2019-10-03
      • 1970-01-01
      • 2021-04-10
      相关资源
      最近更新 更多