使用带有数据的较大数组填充对象数组的属性的最有效方法是什么?

时间:2017-09-30 08:53:37

标签: javascript arrays ecmascript-6

我有一小部分具有属性的对象,如下所示:

  [
    {
      topicName: 'Clicks',
      topic: 1,
      dates: [ <PLACE VALUES HERE> ],
    },
    {
      topicName: 'Cost',
      topic: 2,
      dates: [ <PLACE VALUES HERE> ],
    },
  ];

然后我有一大堆对象,我希望从上面的日期数组中提取一些属性。 这是我希望从中提取的数据:

[
    {
      "date": "2014-02-01",
      "device": "Computer",
      "match-type": "NA",
      "clicks": 66,
      "revenue": 1037,
      "conversions": 2,
      "cost": 284.35,
      "impressions": 5330,
      "ROI": 3.64691401441885
    },
    {
      "date": "2014-02-01",
      "device": "Tablet",
      "match-type": "NA",
      "clicks": 38,
      "revenue": 587,
      "conversions": 2,
      "cost": 194.01000000000005,
      "impressions": 1934,
      "ROI": 3.025617236224936
    },
    {
      "date": "2014-02-02",
      "device": "Tablet",
      "match-type": "NA",
      "clicks": 40,
      "revenue": 587,
      "conversions": 2,
      "cost": 190,
      "impressions": 1934,
      "ROI": 3.025617236224936
    },
  ]

现在我需要来自最后一个数组的所有成员的数据,并在第一个数组中插入特定对象的相关数据(必要时总计),如下所示:

  [
    {
      topicName: 'Clicks',
      topic: 1,
      dates: [
        {
          date: '2014-02-01',
          value: 104
        },
        {
          date: '2014-02-02',
          value: 40
        }
      ],
    },
    {
      topicName: 'Cost',
      topic: 2,
      dates: [
        {
          date: '2014-02-01',
          value: 284,3519401
        },
        {
          date: '2014-02-02',
          value: 190
        }
      ],
    },
  ];

目标是Chrome的最新版本,我使用Webpack和Babel,所以最新的东西都可用。

假设最后一个数据集可能非常大,那么最有效的方法是什么?

[编辑]

这是我到目前为止所提出的:

const dataAdapter = rawData => {
  const topics = ['clicks', 'revenue', 'cost', 'roi'];
  const topicsData = topics.map((topic, index) => {
    const thisTopic = {};

    thisTopic.topicName = topic;
    thisTopic.topic = index;
    thisTopic.dates = [];

    return thisTopic;
  });

  const convertedData = topicsData.map(topicData => {
    const thisTopic = topicData;
    const map = new Map();

    rawData.forEach(elem => {
      map.set(elem.date, (map.get(elem.date) || 0) + elem[[thisTopic.topicName]]);
    });

    thisTopic.dates = Array.from(map);

    return thisTopic;
  });

  return convertedData;
};

谢谢,

/ J

2 个答案:

答案 0 :(得分:2)

您可以将对象作为对所需键和日期的引用。然后迭代数据并检查是否存在对结果集的引用。如果没有,请创建一个新的结果集。

var result = [{ topicName: 'Clicks', topic: 1, dates: [], }, { topicName: 'Cost', topic: 2, dates: [], }],
    data = [{ date: "2014-02-01", device: "Computer", "match-type": "NA", clicks: 66, revenue: 1037, conversions: 2, cost: 284.35, impressions: 5330, ROI: 3.64691401441885 }, { date: "2014-02-01", device: "Tablet", "match-type": "NA", clicks: 38, revenue: 587, conversions: 2, cost: 194.01000000000005, impressions: 1934, ROI: 3.025617236224936 }, { date: "2014-02-02", device: "Tablet", "match-type": "NA", clicks: 40, revenue: 587, conversions: 2, cost: 190, impressions: 1934, ROI: 3.025617236224936 }],
    hash = { clicks: { _: result[0].dates }, cost: { _: result[1].dates }, };

data.forEach(function (o) {
    ['clicks', 'cost'].forEach(function (k) {
        if (!hash[k][o.date]) {
            hash[k][o.date] = { date: o.date, value: o[k] };
            hash[k]._.push(hash[k][o.date]);
            return;
        }
        hash[k][o.date].value += o[k];
    });
});

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

答案 1 :(得分:0)

假设您的数据位于data变量中且主题位于topics变量中。此解决方案仅使用javascript内置对象。

const getPropDateMap = (obj, prop) => obj
  .reduce((accObj, item) => {
    return Object.assign(accObj, {
      [item.date]: item.clicks + (accObj[item.date] || 0)
    })
  }, {})

topics.forEach(topic => {
  topic.dates = Object
    .entries(getPropDateMap(data, topic.topicName.toLowerCase()))
    .map(entry => ({date: entry[0], value: entry[1]}))
})