【问题标题】:Fastest way to "reduce" nested array to object with keys + fastest way to find by key用键“减少”嵌套数组到对象的最快方法 + 用键查找的最快方法
【发布时间】:2019-10-18 15:04:06
【问题描述】:

我需要转换这种类型的嵌套数组,以便能够以最快的方式通过键 (id) 进行搜索:

[
   {
      "id":1,
      "name":"example1",
      "items":[
         {
            "id":1,
            "name":"example1",
            "example":123
         },
         {
            "id":2,
            "name":"example1",
            "example":123
         }
      ]
   },
   {
      "id":2,
      "name":"example1",
      "items":[
         {
            "id":3,
            "name":"example1",
            "example":123
         },
         {
            "id":4,
            "name":"example1",
            "example":123
         }
      ]
   }
]

实际上嵌套数组要多得多(大约 4 层)。

我目前的方法是对每个级别进行reduce,然后我可以使用例如list[1].items[1].name。对我来说,这看起来非常缓慢且效率低下。

我还在stackoverflow 上发现我可以创建查找表id->index,但这看起来具有相同的复杂性并且占用更多内存。

有人有更好的想法来做这样的转变吗?我正在处理大量数据集,我开始觉得我需要找到更好的方法来处理数据。

我这样做是因为我需要通过 ID 在这个数据集中快速搜索。通过findIndex 在数组中搜索很慢。如上所述,转换需要处理。

我需要找到总体复杂度最低的选项。

【问题讨论】:

  • id 出现在多个级别,您对哪一个感兴趣?
  • 查找表确实是要走的路。请说明为什么这对您来说不够好。在您的问题中添加一些代码,以便我们了解您是如何实现它的,以及可能存在问题的地方。您只需进行一次转换,every 搜索即可从中获益。所以这个代价是值得的。
  • 假设你要查找id=1,有两个地方出现了id=1,假设得到哪一个?
  • @sam id 在给定级别上是唯一的

标签: javascript node.js algorithm performance reduce


【解决方案1】:

进行转型。这是值得付出代价的努力,因为您将通过每一次搜索从投资中受益。

这是一个转换为基于Map 的查找表,用于检索关联对象。它将以逗号分隔的 id 值字符串作为查找键:

function makeLookup(list, map=new Map, prefix="") {
    for (let obj of list) {
        map.set(prefix + obj.id, obj);
        if (obj.items) makeLookup(obj.items, map, prefix + obj.id + ",");
    }
    return map;
}


let list = [{ "id":1, "name":"example1", "items":[
     {"id":1, "name":"example2", "example":123},
     {"id":2, "name":"example3", "example":123}
  ]}, { "id":2, "name":"example4", "items":[
     { "id":3, "name":"example5", "example":123 },
     { "id":4, "name":"example6", "example":123 }
  ]}
];

// One-shot transformation
let lookup = makeLookup(list);

// Demo of a loookup
console.log(lookup.get("1,2").name);
console.log(lookup.get("2,3").example);

【讨论】:

  • 那不是内存效率非常低,因为.get(1) 中仍然会有items 数组吗?
  • 它会有那个数组,但那是你的原始数据。它不是它的副本。所以这个 Map 就像它上面的一个索引。如果您愿意,您可以删除这些数组,但这需要额外的时间,并且会影响您的原始结构。同样,它不是副本。
猜你喜欢
  • 1970-01-01
  • 2021-07-20
  • 1970-01-01
  • 2016-02-11
  • 1970-01-01
  • 2010-09-29
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多