Javascript rxjs将2个不同观测值的2个对象组合在一起

Javascript rxjs将2个不同观测值的2个对象组合在一起,javascript,rxjs,Javascript,Rxjs,我有两个分别监听数据库调用的观察对象。我需要将两个数组合并在一起。如果我有以下数组 array1 = [{id: 1, content1: "string"}, {id: 2, content2: "string"}, {id: 3, content3: "string"}] array2 = [{id: 1, contentX: "string"}, {id: 2, contentY: "string"}, {id: 3, contentZ: "string"}] 我想把它们合并在一起,这样

我有两个分别监听数据库调用的观察对象。我需要将两个数组合并在一起。如果我有以下数组

array1 = [{id: 1, content1: "string"}, {id: 2, content2: "string"}, {id: 3, content3: "string"}]
array2 = [{id: 1, contentX: "string"}, {id: 2, contentY: "string"}, {id: 3, contentZ: "string"}]
我想把它们合并在一起,这样我就可以得到一个可观察的数组,如下所示:

[{id:1, content1:"string", contentX:"string"}, {id:2, content2:"string", contentY:"string"}, {id:3, content3:"string", contentZ:"string"}]
我有一些代码,但我真的很困惑如何继续,我似乎无法找到正确的运营商或链他们正确,有人有一个很好的解释如何继续?这就是我到目前为止所拥有的,但实际上我不知道如何继续下去

    const observable1 = getDataFromDb1();
    const observable2= getDataFromDb2();

    observable1 .pipe(
        combineLatest(observable2),
        flatMap(x => {
            //what to do here???
        })
    ).subscribe(
        (value)=>{
            console.log(value);
        }
    )

谢谢你的时间

我在这里做一个大胆的猜测,假设两个源观测值在一个大的块中发出它们的值。如果是这种情况,您只需
将这两种排放映射到自定义的合并排放(否则请留下评论)。例如:

const{of,combineLatest}=rxjs;
const{map}=rxjs.operators;
//按id进行简单合并
const mergeById=([t,s])=>t.map(p=>Object.assign({},p,s.find(q=>p.id==q.id));
const db1$=的([
{id:1,content1:'string'},
{id:2,content2:'string'},
{id:3,content3:'string'},
]);
constdb2$=of([
{id:1,contentX:'string'},
{id:2,contentY:'string'},
{id:3,contentZ:'string'},
]);
constall$=combinelatetest(db1$,db2$).pipe(
映射(mergeById)
);
所有$.subscribe(console.log)

我测试了三种方法:

const entityList1 = [{id: 1, name: 'Bob'}, {id: 2, name: 'John'}, {id: 3, name: 'Mike'}];
const entityList2 = [{id: 3, age: 22}, {id: 1, age: 25}, {id: 2, age: 20}];
@Yoshi的相同版本:

// V0
console.time('V0')
const mergeListsById_v0 = combineLatest(of(entityList1), of(entityList2)).pipe(
  map(([t, s]) => t.map(p => Object.assign({}, p, s.find(q => p.id === q.id))))
).subscribe(x => {
  console.log('result V0:', x);
  console.timeEnd('V0')
});
使用rxjs reduce运算符的版本:

// V1
console.time('V1')
const mergeListsById_v1 = merge(from(entityList1), from(entityList2)).pipe(
  reduce((entitiesById, entity) => {
    return {
      ...entitiesById,
      [entity.id]: {
        ...entitiesById[entity.id] || {},
        ...entity
      }
    };
  }, {}),
  map(entitiesById => Object.values(entitiesById)),
).subscribe(x => {
  console.log('result V1:', x);
  console.timeEnd('V1')
});
// V2
console.time('V2')
const mergeListsById_v2 = merge(from(entityList1), from(entityList2)).pipe(
  groupBy(entity => entity.id),
  mergeMap(groupedEntities$ => groupedEntities$.pipe(
    reduce((merged, entity) => ({...merged, ...entity}), {}))
  ),
  toArray()
).subscribe(x => {
  console.log('result V2:', x);
  console.timeEnd('V2')
});
使用rxjs groupBy运算符的版本:

// V1
console.time('V1')
const mergeListsById_v1 = merge(from(entityList1), from(entityList2)).pipe(
  reduce((entitiesById, entity) => {
    return {
      ...entitiesById,
      [entity.id]: {
        ...entitiesById[entity.id] || {},
        ...entity
      }
    };
  }, {}),
  map(entitiesById => Object.values(entitiesById)),
).subscribe(x => {
  console.log('result V1:', x);
  console.timeEnd('V1')
});
// V2
console.time('V2')
const mergeListsById_v2 = merge(from(entityList1), from(entityList2)).pipe(
  groupBy(entity => entity.id),
  mergeMap(groupedEntities$ => groupedEntities$.pipe(
    reduce((merged, entity) => ({...merged, ...entity}), {}))
  ),
  toArray()
).subscribe(x => {
  console.log('result V2:', x);
  console.timeEnd('V2')
});
您可以在此处使用这些版本:


正如您所看到的,就性能而言,V2要比其他版本好得多。

Rx.Observable.merge(observable1,observable2)、subscribe(x=>console.log(x));您的可观察对象是发出数组
[{id:1,content1:“string”}]
还是发出对象
{id:1,content1:“string”}
?您能描述一下
可观察1
可观察2
是如何发出它们的值的(单独还是一次性)?关系是如何定义的?在这两个集合中是否始终存在id匹配记录?如果它们的不可观测,会发生什么?1和2是对2个不同数据库@Yoshi的http调用。因此,结果将在不同的时间从两个不同的位置得出。总会有一个idmatching@CozyAzure当我记录发射阵列时,它是一个对象阵列