使用combineLatest匹配两个Observable数据对象,获取指定匹配项属性值
Hey there! Let's figure out how to solve this RxJS problem you've got. Here's a step-by-step breakdown and solution that gets you the result you need (with a quick note on a possible typo in your expected result first):
First, let's recap your scenario to make sure we're aligned:
- You have
array1: An Observable that emits an array of user objects (each withnameandlastnameproperties). - You have
array2: An Observable that emits a single string value ('test1'in your example). - Your goal is to create
object3: An Observable that emits thelastnameof the user inarray1whosenamematches the value fromarray2.
Quick note: In your expected result, you listed object3=Observable.of('last'), but since array2 emits 'test1', the matching user's lastname is actually 'last1'. If you meant for array2 to emit 'test', then the result would be 'last'—I'll cover both cases in the solution!
Solution Code (RxJS 6+ Syntax)
Here's how you can implement this using core RxJS operators:
import { of, combineLatest } from 'rxjs'; import { map, filter } from 'rxjs/operators'; // Your original Observables (updated to modern RxJS syntax) const array1 = of({ data: [ { name: 'test', lastname: 'last' }, { name: 'test1', lastname: 'last1' } ] }).pipe(map(res => res.data)); const array2 = of('test1'); // Change this to 'test' if you want 'last' as the result // Create the desired Observable const object3 = combineLatest([array1, array2]).pipe( // Destructure the combined values: the user array from array1, target name from array2 map(([userArray, targetName]) => { // Find the user whose name matches the target const matchingUser = userArray.find(user => user.name === targetName); // Return the lastname if we found a match, or undefined otherwise return matchingUser ? matchingUser.lastname : undefined; }), // Optional: Only emit when a valid match exists (skip undefined) filter(lastname => lastname !== undefined) ); // Test it out! object3.subscribe(result => console.log(result)); // Output: 'last1' (or 'last' if array2 emits 'test')
How It Works
Let's break down the key parts:
combineLatest: This operator takes both Observables and emits a new value whenever either one emits an update. It pairs the latest value fromarray1with the latest value fromarray2—perfect if you need the match to stay updated if either source changes.map: We use this to process the paired values: we search the user array for a match with the target name, then extract thelastnamefrom that user.filter(optional): If you don't wantobject3to emitundefinedwhen there's no matching user, add this step to only pass through validlastnamevalues.
Alternative: Use withLatestFrom if You Only Care About array1 Emissions
If you don't need object3 to re-emit when array2 changes (only when array1 emits, using the most recent value from array2), swap combineLatest with withLatestFrom:
const object3 = array1.pipe( withLatestFrom(array2), map(([userArray, targetName]) => { const matchingUser = userArray.find(user => user.name === targetName); return matchingUser ? matchingUser.lastname : undefined; }), filter(lastname => lastname !== undefined) );
This will only trigger when array1 emits, using the latest value from array2 at that moment.
内容的提问来源于stack exchange,提问作者FrontEndDeveloper

