получить только измененные объекты из наблюдаемого массива с помощью rxjs - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть массив объектов (не примитивов), называемых "полосами" в моем дереве состояний, и я хочу наблюдать только изменения этого массива, а не просто генерировать весь массив каждый раз, когда он изменяется. Когда я пытаюсь сделать это, используя pairwise(), я каждый раз получаю два одинаковых массива, хотя я думал, что pairwise () присоединится к предыдущей и текущей версиям. Почему pairwise () отправляет два одинаковых массива? ПРИМЕЧАНИЕ streaks[1] и streaks[0] идентичны, поэтому _.differenceBy() не находит никаких изменений, поскольку два массива совпадают.

import {from} from "rxjs";
import {map, pairwise} from "rxjs/operators";
import * as _ from 'lodash';

  const state$ = from(store);
  const streaks$ = state$.pipe(
      map(state => state.streaks),
      // distinctUntilChanged(), <-- i've tried this and nothing is output at all
      pairwise(),
      map(streaks => {
        let diff = _.differenceBy(streaks[0], streaks[1], _.isEqual);
        console.log('diff', diff); //<-- this is an empty array
        return diff;
      })
  );

  streaks$.subscribe((streaksArray) => {
    console.log('STREAKS$ 0', streaksArray); //<-- this is never even hit
  } );

1 Ответ

0 голосов
/ 14 февраля 2020

Я решил эту проблему, создав differentUntilChanged Array оператор, который использует самописную compareArray функцию

Создать массив сравнения функция

const compareArray<T> = (first: T[], second: T[], comparator=: (obj: T, obj2: T) => boolean): boolean {
  return (first.length === 0 && second.length === 0)
    || (first.length === second.length && first.every((value, index) => {
         return comparator
           ? comparator(value, second[index])
           : JSON.stringify(value) === JSON.stringify(second[index]);
    }))
}

Может быть, вы найдете лучший компаратор массива. Это только моя личная реализация этого

Создать отдельный оператор UnilChangedArray


const distinctUntilChangedArray<T> = (comparator?: (prev: T, curr: T) => boolean): MonoTypeOperatorFunction<T[]> {
  return distinctUntilChanged((prev: T[], curr: T[]) => {
    return compareArray(first, second, comparator);
  }
}

Окончательное использование

interface nonPrimitive {
  id: number;
  name: string;
}

const nonPrimitiveComparator = (prev: nonPrimitive, curr: nonPrimitive): boolean => {
  return prev.id === curr.id && prev.name === curr.name;
}

const source$: Observable<nonPrimitive>;

const distinctedSource$ = source$.pipe(
  distinctUntilChangedArray(nonPrimitiveComparator)
);
...