【问题标题】:What are the differences between Array map and rxjs mapArray map 和 rxjs map 有什么区别
【发布时间】:2023-03-04 12:22:01
【问题描述】:

我想知道 rxjs 和数组上的地图以相同的方式工作。数组map方法和rxjs map操作符的使用有什么区别?

【问题讨论】:

  • 我不熟悉 RxJS 中的 .map,但这本身就是一个非常笼统的概念。它根本不源于 JS 数组或 JS - 映射函数总是接受类型 A 的输入并产生类型 A 或 B 的输出(int -> int 代表 x => x*1 或 int -> string 代表 x => "My number is: " + x)。在其他情况下,您可以为一个对象创建一个容器,然后使用 container.map() 与底层值交互并更改底层值(例如,Java Optional),或者您可以在数组上使用 .map 来更改所有值。不过,这是同一个想法。

标签: javascript arrays rxjs


【解决方案1】:

Array.map 转换单个数组的每个元素

console.log( [ 1, 2, 3 ].map(x => x * x) )
// log: [ 1, 4, 9 ]

一般来说,RXJS Observables 更像是一个数据流,但是每个数据都是它自己的实体。

您可以选择将数组存储在 Observable 中,但每个数组仍被视为单个实体。每次您拨打Subject#next 时,您都会提供一个全新的数组。在这种情况下,RXJS 中没有与Array#push 等效的方法,因为 RXJS 并不关心 Observable 的内容恰好是一个数组。

// Observable that holds an array as its type
const subject: Subject<number[]> = new Subject<number[]>();
subject.pipe(
  // the value here is a full array
  map(arr => arr.map(x => x * x))
).subscribe(arr => console.log(arr));

subject.next([ 1, 2, 3 ]);
// log: [ 1, 4, 9 ]

subject.next([ 7, 8, 9 ]);
// log: [ 49, 64, 81 ]

* 奖励:如果您设置ReplaySubject,您可以有点让某些东西更像一个数组。 Subject 的这种实现实际上重放了所有提供给它的数据(或基于您如何实例化它的子集)。正如您将看到的,对此的限制是您只能推到最后,并且您必须创建一个新订阅才能查看整个“数组”,但这仍然是一个有趣的思想实验。

const subject: ReplaySubject<number> = new ReplaySubject<number>();
subject.next(1);
subject.next(2);
subject.next(3);

const transformed: Observable<number> = subject.pipe(
  map(x => x * x)
);

transformed.pipe(first()).subscribe(x => console.log(x));
// log: 1
// log: 4
// log: 9

subject.next(9);
transformed.pipe(first()).subscribe(x => console.log(x));
// log: 1
// log: 4
// log: 9
// log: 81

【讨论】:

    【解决方案2】:

    它们的功能完全相同,它们分别给出一个新的 Array / Observable,每个元素根据(通常)转换函数进行转换(技术计算机科学名称将是 投影) ,将修改后的对象及其索引作为参数。

    Array.map 是原生 Array 原型的一部分。您可以在任何 JavaScript 环境中的任何数组上使用它。 (当然,前提是你没有弄乱 Array.prototype)

    Observable.map 必须被导入。 (对于 RxJS 6:import { map } from 'rxjs/operators';,对于旧版本:import { map } from 'rxjs/add/operator/map'


    有一个小而显着的差异

    Array.map 变换函数可以访问被变换的整个数组(投影函数中的第三个参数)。

    示例:

         let arr = ['a', 'b', 'c'];
         let arrResult = arr.map(
           (elem, index, wholeArray) => 'element ' + elem + ' was in position ' + index + ' in array ' + wholeArray);
         console.log(arrResult);

    这在 Observable 的上下文中“当然”是不可能的(一般来说),因为在每个元素被发射时可能不知道发射值的“整个列表”。


    相反,还有另一个小区别:Observable.map 运算符采用(可选)thisArg 参数,因此转换函数可以访问某些指定的上下文。

    我认为这个其他区别是非常微不足道的:Array.map 不需要这个,因为它是一个函数,您也可以使用 JavaScript 中调用函数的各种方式指定自己的“this”。 (我没有找到这部分的好链接,欢迎任何想在这个答案中添加参考的人)。

    另外,无论如何,我会觉得在最后一点上受到挑战很有趣。

    【讨论】:

      【解决方案3】:

      RxJS 用于使用 Observables,而原生 map 用于 Arrays。 这是我能想到的唯一区别。

      【讨论】:

      • 所以你认为我们使用 rxjs map 操作符和我们使用数组 map 方法操作数据的方式一样,还是有什么不同?
      • Pac0 解释得更好。
      猜你喜欢
      • 2014-11-20
      • 2020-08-01
      • 1970-01-01
      • 2016-12-24
      • 2018-03-08
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      • 2013-03-14
      相关资源
      最近更新 更多