2

I have an Observable array which looks like this:

persons$: Observable<Person[]> = new Observable<Person[]>();
private personSource: BehaviorSubject<Person[]>;

  constructor() {
    this.personSource = new BehaviorSubject<Person[]>([
    new Person('Meenique'),
    new Person('Wolfcastle'),
    new Person('Stradivarius Cain'),
    new Person('Wiggum'),
    new Person('McKenna'),
    new Person('Flanders'),
    new Person('Kent Brockman'),
    new Person('Manjula')
]);

Now, I want to select values between given property. eg: 'Name'

async selectBetween(start: string, end: string): Promise<Person[]> {
// return this.persons$.pipe(map(p => p.Name)).toPromise();
}

The selectBetween function will take two sting values. In this case, the Person.Name, and should return all values between given names.

e.g:

const test1 = await this.selectBetween('Wolfcastle', 'McKenna');

Should return: [Wolfcastle, Stradivarius Cain, Wiggum, McKenna]

Here my StackBlitz example:

https://stackblitz.com/edit/example-rxjs-observable-create-from-scratch-pqvmqj?file=app/app.component.ts

  • 1
    This isn't really RxJS related or where's the problem? You'll just collect items from an array and return them. – martin Jul 26 '21 at 13:52
  • Under what conditions is one name “less than” another? Is it solely based on position in the array? – Heretic Monkey Jul 26 '21 at 14:04

1 Answers1

1

Not sure why you want to involve Promises in here but if you really want to do that you can probably find a way to do the conversion better than me as I'm never mixing the two.

Anyways, this returns an observable with an array of person that were between the two given names:

  selectBetween(start: string, end: string): Observable<Person[]> {
    return this.persons$.pipe(
      map(pArray => {
        const startIndex = pArray.findIndex(p => p.name === start);
        const endIndex = pArray.findIndex(p => p.name === end);
        return pArray.filter((p, i) => i >= startIndex && i <= endIndex);
      })
    );
  }

Stackblitz:

https://stackblitz.com/edit/example-rxjs-observable-create-from-scratch-xq1nvf?file=app/app.component.ts

Edit: this returns the whole Person objects, if you just want the name values just edit the last line:

return pArray.filter((p, i) => i >= startIndex && i <= endIndex).map(p => p.name);

Sleepwalker
  • 803
  • 3
  • 11
  • This will only work if the array is already sorted by name. Given the array as is from the OP, passing `‘Wolfcastle’, ‘Wiggum’`, with this code, the result would include ‘Stradivarius Cain', which seems unintuitive. – Heretic Monkey Jul 26 '21 at 14:03
  • 2
    @HereticMonkey That's clearly what OP wants from the exemple he gave: "`const test1 = await this.selectBetween('Wolfcastle', 'McKenna');` Should return: [Wolfcastle, Stradivarius Cain, Wiggum, McKenna]" – Sleepwalker Jul 26 '21 at 14:05