将数据结构重新映射到总计中的对象列表

时间:2021-01-08 05:20:21

标签: javascript arrays

我的数据目前是:

var data = [
  {"date":"01/2020", "x":1, "y":3, "z":4},
  {"date":"02/2020", "x":2, "y":4, "z":6},
  ...
];

我想要的输出是:

var data2 = [
  {date:"01/2020", type:"x"},
  {date:"01/2020", type:"y"},
  {date:"01/2020", type:"y"},
  {date:"01/2020", type:"y"},
  {date:"01/2020", type:"z"},
  {date:"01/2020", type:"z"},
  {date:"01/2020", type:"z"},
  {date:"01/2020", type:"z"},
  {date:"02/2020", type:"x"},
  {date:"02/2020", type:"x"},
  {date:"02/2020", type:"y"},
  {date:"02/2020", type:"y"},
  {date:"02/2020", type:"y"},
  {date:"02/2020", type:"y"},
  {date:"02/2020", type:"z"},
  {date:"02/2020", type:"z"},
  {date:"02/2020", type:"z"},
  {date:"02/2020", type:"z"},
  {date:"02/2020", type:"z"},
  {date:"02/2020", type:"z"},
  ...
];

本质上,我的目标是解压缩数据中的总数并将它们配置为对象格式,以便对象数等于总数。例如,如果 y=3 在一月份,那么我们在 {date:"01/2020", type:"y"} 中有 3 次出现 data2

我不太确定如何实现这一目标。我只能以一种粗略/不可扩展的方式扩展一种微不足道的类型:

var data2 = d3.range(3).map(()=>({"type":"y"}));

问题

如何根据原始数组的总数构建用于使用对象填充新数组的逻辑?

3 个答案:

答案 0 :(得分:3)

您可以在 data 数组上使用 Array.reduce,处理每个对象并将 date 和其他每个 key 值作为对象推送到您的输出数组中,在其中按与键关联的值指定的次数推送每个对象:

var data = [
  {"date":"01/2020", "x":1, "y":3, "z":4},
  {"date":"02/2020", "x":2, "y":4, "z":6}
];
var data2 = data.reduce((c, { date, ...rest }) => {
  Object.entries(rest).map(([type, v]) => {
    for (let i = 0; i < v; i++) {
      c.push({ date, type });
    }
  });
  return c;
}, []);

console.log(data2);

答案 1 :(得分:2)

您可以使用 .flatMap() 来迭代您的数据数组。对于数据数组中的每个对象,您可以获取该对象除date属性外的条目(该对象存储在r中,通过destructuring assignment获取),并通过映射那些返回每个值长度的新数组。使用这个新数组,您可以用 {date, type} 对象填充它。我们在这里使用 .flatMap() 是因为它允许我们将返回的结果展平/连接到一个结果数组中:

const data = [{"date":"01/2020", "x":1, "y":3, "z":4}, {"date":"02/2020", "x":2, "y":4, "z":6},];

const data2 = data.flatMap(({date, ...r}) => Object.entries(r).flatMap(
  ([type, length]) => Array.from({length}, _ => ({date, type}))
));

console.log(data2);
.as-console-wrapper { max-height: 100% !important;} /* ignore */ 

答案 2 :(得分:1)

您可以执行以下操作,

var data = [

{"date":"01/2020", "x":1, "y":3, "z":4},
{"date":"02/2020", "x":2, "y":4, "z":6},
];
  

res = data.reduce((prev, curr) => {
  Object.keys(curr).forEach(key => {
    if(key !== 'date') {
      for(let i = 0; i<curr[key]; i++) {
        prev.push({ date: curr.date, type: key});
      }
    }
  });
  return prev;
}, []);

console.log(res)