使用 Ramda 将对象数组转换为嵌套对象

Transform array of objects to nested objects using Ramda

我是新手,请原谅我问了一个幼稚的问题。

我有一个对象数组

const arr = [{id: 1, name: 'Pete'}, {id: 5, name: 'John'}, {id: 3, name: 'Peter'}]

我想使用 ramda 将其转换为这种形式:

const obj = {1 : {id: 1, name: 'Pete'}, 5: {id: 5, name: 'John'}, 3: {id: 3, name: 'Peter'}} 

有人可以帮忙吗?

其他概念性问题:

  1. 我想将嵌套的对象数组转换为这种形式,因为如果给出 id,这样搜索 name 会很快。这是正确的方法吗?
  2. 是否有任何其他有效的方式可以提高数组的搜索速度?

谢谢

如果没有 ramda,您可以使用 build-in Object.fromEntriesid 和对象的映射。

const
    array = [{ id: 1, name: 'Pete' }, { id: 2, name: 'John' }, { id: 3, name: 'Peter' }],
    object = Object.fromEntries(array.map(o => [o.id, o]));

console.log(object[2].name);
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }

你可以使用 ramda 的 R.indexBy:

const arr = [{id: 1, name: 'Pete'}, {id: 2, name: 'John'}, {id: 3, name: 'Peter'}]

const result = R.indexBy(R.prop('id'))(arr)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>

I want to convert nested array of objects to this form because that way searching a name will be quick if id is given. Is this the right approach?

从数组中获取一个项目通常是 O(n)。通过 属性 从对象(字典)中获取项目的索引是 O(1),因此对象获胜...如果您想通过 id 获取名称。但是,如果您要按名称查找对象,则应按 name 属性 进行索引。此外,您是否要查找确切的名称?或包含某些东西的名称。如果搜索的是名称的一部分,那么您仍然需要迭代所有内容 O(n),数组也应该没问题。

Is there any other efficient way performance wise that can make the search in array quicker?

这实际上取决于您要如何搜索,以及您要搜索的项目数量,如果您少于 50,000 并且搜索 hy id - 对象或地图将是很好,通过名称的一部分 - 数组就可以了。但是,在你真正遇到问题之前不要尝试优化,你分析它,发现搜索是罪魁祸首。

您可以尝试一个过滤器 - 这会使原始数组保持原样,returns 一个包含匹配项的新数组:

const arr = [{id: 1, name: 'Pete'}, {id: 2, name: 'John'}, {id: 3, name: 'Peter'}]


let filtered = arr.filter(a => a.id == 1);
console.log(filtered);

您可以在此处使用 Map 以获得更好的性能。

const map = new Map();
const arr = [{id: 1, name: 'Pete'}, {id: 2, name: 'John'}, {id: 3, name: 'Peter'}]

for(const {id, name} of arr){
  map.set(id, name);
}

//check id exists 
map.has(1)  // true
//get person's name
map.get(1) //"Pete"