是的,我知道类似的问题,但是这里并没有涵盖我的用例。
我在寻找降低时间复杂度的方法时遇到了困难
我有两个这样的对象
const people = [
{
name: 'Steve',
id: 1,
fruitInBasket: 6
},
{
name: 'James',
id: 2,
fruitInBasket: 4
}
]
const homes = [
{
id: 1,
familyMembers: [
{
name: 'James',
id: 2
},
{
name: 'Steve',
id: 1
}
]
},
{
id: 2,
familyMembers: [
{
name: 'James',
id: 2
},
{
name: 'Steve',
id: 1
}
]
}
]
因此,一个是people
的集合,篮子里有很多水果,另一个是homes
的集合,每个家庭中的用户与people
中的用户相同集合。
现在我想根据fruitInBasket
的数量对每个家庭中的用户进行排序,所以我已经完成了
// create an empty table to store the order of the people
let orderTable = {};
// order the people based off the count in fruitInBasket using lodash orderBy
people = orderBy(people, ['fruitInBasket'], ['desc']);
// create the table
orderTable = people.reduce((acc, item, index) => {
return {
...acc,
[item.id]: index
}
}, {});
// order the people in each home based on the order in the `orderTable`
homes.forEach((home) => {
let members = [];
home.familyMembers.forEach((member) => {
let i = orderTable[member.id];
members[i] = member;
});
home.familyMembers = members;
})
因此,您立即可以看到嵌套的for循环-从来都不是理想的..但是我找不到解决该问题的方法。此方法必须整理大量数据,我注意到巨大的性能问题。
任何帮助将不胜感激!
答案 0 :(得分:2)
这应该是O(N log N)。它的性能瓶颈是一次性的。其他一切只是O(N)迭代。仍然可以进行一些微优化。
生成有序的地图查找表。
只需根据该映射移动数组。
有一个hpc排序库,在基准测试中,它的测量速度比内置JavaScript快10至40倍,可以添加基准以提高性能。
我不确定,但是familyMember表是否对于每个主对象都一样?您不仅可以将相同的familyMember数组复制到每个对象,还是它们具有不同的属性?
每个家庭的额外优化可能是将上表转换为索引到索引的映射,以便将本机级数组索引用于后续排序。
/db/app/oracle/product/11.2.0.3/dbhome_1
const orderMap = Object.fromEntries(people.sort((x,y)=>x.fruitInBasket-y.fruitInBasket).map(({id},i)=>[id,i]))
// O(N)+O(NlogN)
homes.forEach(home=>{
const {familyMembers:fms} = home
const arr = new Array(fms.length)
//may want to prefill to maintain PACKED array: https://v8.dev/blog/elements-kinds#avoid-creating-holes
for(const fm of fms) arr[ orderMap[fm.id] ] = fm
home.familyMembers = arr
})
// map lookup O(N)
console.log(homes)
答案 1 :(得分:1)
您可以过滤和排序:
const people = [
{
name: 'Steve',
id: 1,
fruitInBasket: 6
},
{
name: 'James',
id: 2,
fruitInBasket: 4
},
{
name: 'Cesar',
id: 3,
fruitInBasket: 14
}
]
const homes = [
{
id: 1,
familyMembers: [
{
name: 'James',
id: 2
},
{
name: 'Cesar',
id: 3
},
{
name: 'Steve',
id: 1
}
]
},
{
id: 2,
familyMembers: [
{
name: 'James',
id: 2
},
{
name: 'Steve',
id: 1
}
]
}
]
homes.forEach(function(home){
home.familyMembers.sort((a,b)=>people.find(x=>x.id == a.id).fruitInBasket - people.find(x=>x.id == b.id).fruitInBasket)
})
console.log(homes)
说明:
您将遍历房屋:
homes.forEach(function(home){
您将对成员进行排序
.familyMembers.sort((a,b)
要进行排序,您必须获取成员的果实,因此您找到正确的ID,然后采用正确的属性:
people.find(x=>x.id == a.id).fruitInBasket
然后您进行比较:
(a,b)=>people.find(x=>x.id == a.id).fruitInBasket - people.find(x=>x.id == b.id).fruitInBasket
如果您要寻找的是性能,则应更改people
结构:
const people = {
1: {
name: 'Steve',
fruitInBasket: 6
},
2: {
name: 'James',
fruitInBasket: 4
}
}
这样,您可以更轻松地获取水果:
people[id].fruits
此外,如果您的“ id”是在某处定义的,则不要在其他地方定义它。您的homes
应该如下所示:
const homes = {
1: {
familyMembers: [1, 2, 3]
},
2: {
familyMembers: [1,2]
}
}
所以您的算法如下:
const people = {
1: {
name: 'Steve',
fruitInBasket: 6
},
3: {
name: 'James',
fruitInBasket: 4
},
2: {
name: 'Cesar',
fruitInBasket: 9114
}
}
const homes = {
1: {
familyMembers: [1, 2, 3]
},
2: {
familyMembers: [1,2]
}
}
Object.keys(homes).forEach(function(k){
homes[k].familyMembers.sort((a,b)=>people[a].fruitInBasket - people[b].fruitInBasket)
})
console.log(homes)