Rxjs - Сравнение .map () с map () - PullRequest
       11

Rxjs - Сравнение .map () с map ()

1 голос
/ 03 октября 2019

Сравните это

return this.httpClient.get('https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest', {params: data}).pipe(
            map((x: any) => x.suggestions.map((y) => {
                return {
                    ...y,
                    title: y.text
                };
            })),
        );

с этим

return this.httpClient.get('https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest', {params: data}).pipe(
            map((x: any) => x.suggestions),
            map((y: any) => y.title = y.text)
        );

Почему эти случаи не равны?

Первая работа, как и ожидалось, "удалить" свойство предложений идублировать текст свойства в заголовок

Второй возвращает мне значение ... не массив

Могу ли я использовать только функцию map () вместо .map ()?

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Первая - это карта оператора RxJS, а вторая - функция карты Array.

Давайте рассмотрим типы в вашем примере:

В первом примере вы получаете Observable объекта,В этом случае оператор карты позволяет вам преобразовать ваш объект с массивом предложений внутри него. Затем с помощью функции map массива вы отображаете каждый элемент из массива x.suggestions на новый элемент.

const obs$: Observable<{ suggestions: any[] }> = this.httpClient.get('url', { params: data });
obs$.pipe(
  map((x: { suggestions: any[] }) => x.suggestions.map((y) => {
    return {
      ...y,
      title: y.text
    };
  })),
);

Во втором примере после первого оператора map вы получаете наблюдаемый массив. Таким образом, у второго оператора карты есть ошибка.

const obs$: Observable<{ suggestions: any[] }> = this.httpClient.get('url', { params: data });
const tmp$: Observable<any[]> = obs$.pipe(
  map((x: { suggestions: any[] }) => x.suggestions),
);
tmp$.pipe(
  map((x: any[]) => x.title = x.text) // this line has error: Property 'title' does not exist on type 'any[]'.
)

Поскольку у вас есть Observable для массива, вы отображаете каждый элемент, который является массивом, излучаемым из Observable, в новый элемент.

В случае массива вы сопоставляете каждый элемент, который является объектом из массива, с новым элементом.

Вы думаете, что в Observable of Array это позволит вам отображать элементыот массива до новых предметов, но это не так. Это позволяет вам сопоставить весь массив с тем, что вы хотите.

В качестве решения того, что вы хотели сделать, посмотрите на это:

this.httpClient.get('url', { params: data })
  .pipe(
    switchMap(x => x.suggestions),
    map(x => (...x, title: x.text)),
    toArray(),
  )

Теперь через switchMap вы получаете Observable элементов (вместо Observable для массива) и можете сопоставить каждый элемент по своему желанию, а затем преобразовать его обратно в Observable для массива с помощью оператора toArray.

0 голосов
/ 03 октября 2019

В первом вы используете .map()

return this.httpClient.get('https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest', {params: data}).pipe(
                map((x: any) => x.suggestions.map((y) => {
                    return {
                        ...y,
                        title: y.text
                    };
                })),
            );

Вы используете suggestions.map()

Функции .map() возвращают и массив. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

посмотрите, что делает карта () из rxjs https://www.learnrxjs.io/operators/transformation/map.html

...