javascript - 按键合并数据——减少运行时间

标签 javascript d3.js

我有两个对象数组,我想通过一个键将一些数据从一个对象数组合并到另一个数组。我有一个工作解决方案,涉及嵌套 for 循环,但考虑到我的数据,这需要几秒钟的时间。我怎样才能让它更快?我在我的项目中使用 D3 v5。

// Generate data.
let geo = [],
  cases = [];
for (let j = 0; j < 10000; j++) {
  geo.push({
    fips: j,
    name: `foobar ${j}`
  })
  cases.push({
    fips: j,
    time: 0,
    value: Math.floor(Math.random() * 1000)
  })
  cases.push({
    fips: j,
    time: 1,
    value: Math.floor(Math.random() * 1000)
  })
  cases.push({
    fips: j,
    time: 2,
    value: Math.floor(Math.random() * 1000)
  })
}
// Order is not guaranteed.
d3.shuffle(geo);
d3.shuffle(cases);

// Print some example data.
console.log(geo[0]);
console.log(cases[0]);


// Merge some data.
for (let gi = 0; gi < geo.length; gi++) {

  for (let ci = 0; ci < cases.length; ci++) {

    if (geo[gi].fips === cases[ci].fips) {
      let thisTime = cases[ci].time;
      geo[gi][thisTime] = {
        "cases": cases[ci].value
      };
      // Cannot break out of loop early because there can be multiple matching 
      // rows in `cases` for each row in `geo`.
    }
  }
}

// Print example of merged data.
console.log("After loops...")
console.log(geo[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

最佳答案

您可以将 cases 数组转换为由 fips 属性索引的对象,其值是要合并到 geo 项中的对象,O(n)。然后迭代 geo 项,并通过查找刚刚构造的对象上的 fips 属性来Object.assign 给它们,也 O(n):

// Generate data.
let geo = [],
  cases = [];
for (let j = 0; j < 10000; j++) {
  geo.push({
    fips: j,
    name: `foobar ${j}`
  })
  cases.push({
    fips: j,
    time: 0,
    value: Math.floor(Math.random() * 1000)
  })
  cases.push({
    fips: j,
    time: 1,
    value: Math.floor(Math.random() * 1000)
  })
  cases.push({
    fips: j,
    time: 2,
    value: Math.floor(Math.random() * 1000)
  })
}
// Order is not guaranteed.
d3.shuffle(geo);
d3.shuffle(cases);

// Merge some data.
const caseValueObjsByFips = {};
for (const aCase of cases) {
  if (!caseValueObjsByFips[aCase.fips]) caseValueObjsByFips[aCase.fips] = {};
  caseValueObjsByFips[aCase.fips][aCase.time] = { cases: aCase.value };
}
for (const item of geo) {
  Object.assign(item, caseValueObjsByFips[item.fips]);
}
// Print example of merged data.
console.log("After loops...")
console.log(geo[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

关于javascript - 按键合并数据——减少运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60983975/

相关文章:

javascript - 未捕获的 TypeError : . 过滤器不是函数

javascript - 在页面关闭时,触发注销功能

javascript - ember js 从 json 获取元信息

javascript - JavaScript 中的对象操作

javascript - Angular 2 D3 事件、变更检测和上下文

javascript - 平移传单 map 时 d3 SVG 被切断

svg - 如何使用d3.js更新现有svg元素的填充颜色?

javascript - d3.js - 如何水平扩展力定向图?

javascript - 在 Typescript 中使用默认值解构属性

javascript - Ng-class - 在将类添加到 DOM 后删除它