1
votes

I've got these streams

const site = of([
  { name: 'Joe', age: 30, tsUpdate: 5 },
  { name: 'Frank', age: 20, tsUpdate: 4 },
  { name: 'Ryan', age: 50, tsUpdate: 4 }
]);
const db = of([
  { name: 'Jonas', age: 30, tsUpdate: 4 },
  { name: 'Frank', age: 21, tsUpdate: 8 },
  { name: 'Calgor', age: 50, tsUpdate: 4 },
  { name: 'Joe', age: 30, tsUpdate: 4 },
]);

The goal is to have a single array with distinct value for

name but with the highest tsUpdate

So for instance

 { name: 'Joe', age: 30, tsUpdate: 5 }
 { name: 'Joe', age: 30, tsUpdate: 4 }

I want

{ name: 'Joe', age: 30, tsUpdate: 5 }

I am able to have distinct value for name property but I don't know how to pick the highest value for tsUpdate

https://stackblitz.com/edit/rxjs-mhept2?devtoolsheight=60

1

1 Answers

1
votes

This could be a way to solve it:

forkJoin(
  [
    site, 
    db
  ]
).pipe (
    map(([site, db]) =>  [...site, ...db]),
    
    // Emit each item individually
    mergeAll(),

    // Group by their name
    groupBy(o => o.name),

    // For each separate group, find the object with the highest `tsUpdate`
    mergeMap(
      grp$ => grp$.pipe(
        reduce((acc, crt) => crt.tsUpdate > acc.tsUpdate ? crt : acc),
      ),
    ),

    // At the end, collect all the objects in an array
    toArray(),
    
).subscribe(console.log);

A groupBy's group is a Subject, and that's why we can use mergeMap afterwards. That subject will emit whenever it finds an object that matches with its key.

StackBlitz.