Javascript 按ID合并两个对象数组

Javascript 按ID合并两个对象数组,javascript,arrays,json,reactjs,Javascript,Arrays,Json,Reactjs,我有两个这样的阵列: let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}]; let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}]; result = [ {name: "apple", prices: [{id: 1, price: 50}, {id: 1, price: 40}]}, {name: "

我有两个这样的阵列:

let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];
result = [ {name: "apple", prices: [{id: 1, price: 50}, {id: 1, price: 40}]}, {name: "orange", prices: [{id: 2, price: 30}]}, {name: "others", prices: [{id: null, price: 80}]}] 
现在我想要这样的结果:

let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];
result = [ {name: "apple", prices: [{id: 1, price: 50}, {id: 1, price: 40}]}, {name: "orange", prices: [{id: 2, price: 30}]}, {name: "others", prices: [{id: null, price: 80}]}] 

我想根据数组
id
s,将数组
a
的元素映射到第二个数组
b
的名称。

下面是一种使用
reduce
构建查找集并避免在
b
中重复搜索的方法。另一个简化过程使用查找表按名称构建结果数组。最后,
map
用于格式化结果

时间复杂度是线性的(三次通过,有很多恒定时间的对象查找)

let a=[{id:1,price:50},{id:2,price:30},{id:1,price:40},{id:null,price:80}];
设b=[{id:1,名称:“apple”},{id:2,名称:“orange”}];
const lookup=b.reduce((a,e)=>{
a[e.id]=e.name;
返回a;
}, {});
const result=Object.entries(
a、 减少((a,e)=>{
const key=lookup[e.id]| |“others”;
如果(!(输入a)){
a[键]=[];
}
a[键]。按(e);
返回a;
}, {})
).map(e=>({name:e[0],prices:e[1]}));

控制台日志(结果)在结果的价格部分不重复
id
,因为id与名称一起属于

我建议使用临时的
地图
(为了提高效率):

let a=[{id:1,price:50},{id:2,price:30},{id:1,price:40},{id:null,price:80}];
设b=[{id:1,名称:“apple”},{id:2,名称:“orange”}];
constmap=newmap(b.map(o=>[o.id,Object.assign(o,{prices:[]}]))
.set(null,{id:null,名称:“其他”,价格:[]});
a、 forEach(o=>map.get(o.id).prices.push(o.price));
const result=[…map.values()];

控制台日志(结果)是的,只需一个映射和一个过滤器就可以完成

let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

b.map(({ name, id }) => ({
  name,
  id,
  prices: a.filter(item => item.id === id).map(({ price }) => price)
}));

您可以使用单个阵列执行此操作,如果您首先将两个阵列组合在一起:

let a=[{id:1,price:50},{id:2,price:30},{id:1,price:40},{id:null,price:80}];
设b=[{id:1,名称:“apple”},{id:2,名称:“orange”}];
const result=Object.values([…b,…a])。reduce((r,c)=>{
if('name'在c | | c.id==null)
r[c.id | |'其他']=({name:c.name | |'其他',价格:[]))
if(c中的“name”)
返回r
else if(c.id!=null)
r[c.id].prices.push(c)
其他的
r['其他人].价格.推送(c)
返回r
}, {}))

log(result)
苹果的价格应该是
[{id:1,price:50},{id:1,price:40}]
吗?这只是我遇到的真正问题的一个例子。我确实举了一个不好的例子,但我确实想要我写的。我对结果感到困惑。你说你希望
a
根据它们的id映射到
b
,但是
{id:1,price:40}
中的
a
映射到“apple”,但它不在结果中的apple对象中?为什么要用每个price重复id?当然,同一数组中出现的价格的id将是相同的。似乎更适合避免这种重复,并将id放在输出结构的名称级别。对我的评论和下面的答案有什么反馈吗?
map
*
filter
=O(n²)。