首页 > 解决方案 > 将对象数组转换为嵌套数组以构建图表

问题描述

我有以下数组

const data = [
      {
        date: "2018-01-01",
        label: "MH",
        qt: 10
      },
      {
        date: "2018-04-01",
        label: "MH",
        qt: 30
      },
      {
        date: "2018-02-01",
        label: "GJ",
        qt: 30
      },
      {
        date: "2018-03-01",
        label: "KL",
        qt: 30
      },
      {
        date: "2018-02-01",
        label: "KL",
        qt: 40
      }
    ]

我希望我的输出是

[
  [date,MH,GJ,KL],
  ['Jan 2018',10,null,null],
  ['Feb 2018',null,30,40],
  ['Mar 2018',null,null,30],
  ['Apr 2018',30,null,null]
]

我怎样才能以优化的方式实现这一目标?并且日期应该按顺序排序。我试着做

data.sort(function compare(a, b) {
      var dateA = new Date(a.date);
      var dateB = new Date(b.date);
      return dateA - dateB;
    });
    let labelArr = data.map(l => l.label);
    let dateArr = data.map(l => l.date);
    labelArr = _.uniq(labelArr);
    dateArr = _.uniq(dateArr);
    console.log(labelArr, dateArr);

    const outputArr = [];
    dateArr.forEach(d => {
      labelArr.forEach(l => {
        const tempObj = data.filter(r => {
          if (d == r.date && l == r.label) {
            return r;
          }
          else {
            return { date: d, label: l, qt: null }
          }
        })
        outputArr.push(tempObj);
      });
    });

但我被困在这里。我在想的是首先我将为不存在的日期和标签创建对象,并将他们的 qt 添加到 null。之后,我将按日期分组,然后仅将 qt 插入结果

标签: javascriptarraysjsonjavascript-objects

解决方案


您可以使用一个对象来保存每个日期的数组,并使用一个对象来跟踪列的索引。

最后将所有元素设置null为未设置的项目。

var data = [{ date: "2018-01-01", label: "MH", qt: 10 }, { date: "2018-04-01", label: "MH", qt: 30 }, { date: "2018-02-01", label: "GJ", qt: 30 }, { date: "2018-03-01", label: "KL", qt: 30 }, { date: "2018-02-01", label: "KL", qt: 40 }],
    cols = {},
    rows = {},
    result = data
        .sort(({ date: a }, { date: b }) => a > b || -(a < b))
        .reduce((r, { date, label, qt }) => {
            date = date.slice(0, 7);
            if (!rows[date]) r.push(rows[date] = [date]);
            if (!cols[label]) cols[label] = r[0].push(label) - 1;
            rows[date][cols[label]] = (rows[date][cols[label]] || 0) + qt;
            return r;
        }, [['date']])
        .map((a, _, [{ length }]) => Array.from({ length }, (_, i) => a[i] || null));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


推荐阅读