【问题标题】:What's the difference between map and pluck in RxJS?RxJS 中的 map 和 pluck 有什么区别?
【发布时间】:2021-04-26 23:40:26
【问题描述】:

我试图了解 RxJS 中 mappluck 转换运算符之间的区别。

谁能帮我解决这个问题?

【问题讨论】:

  • 您阅读文档了吗?试试看?您还有什么具体问题?

标签: rxjs


【解决方案1】:

文档说

Pluck : 类似于 map,但仅用于选择其中一个 嵌套 每个发射对象的属性

因此,假设你有

[{ name: 'Joe', age: 30, job: { title: 'Developer', language: 'JavaScript' },
{ name: 'Sarah', age: 35 }]

并且您想要一份所有职位的列表。

使用map 会有点痛苦(因为job 的可空性),但是使用“pluck”你可以写pluck('job', 'title'),它会遍历树来寻找job.title - 并且赢了'如果job 为空,则不会失败。

示例来自:https://www.learnrxjs.io/operators/transformation/pluck.html

https://jsfiddle.net/btroncone/n592m597/

【讨论】:

  • 在您的示例中,我只将“未定义”打印到控制台?
  • 这是一个人的数组,所以你必须在 data[0].pluck('job', 'title') 处执行 data 已分配给 JSON
【解决方案2】:

正如@mgm87 所说,您可以使用map 执行操作。 相反,pluck 只是取值。

例如,使用地图,您可以执行以下操作:

this.http.get('...some api url to get a user...')
  .map(response => response.json())
  .map(user => user.age > 18 ? 'major': 'minor')
  .do(isMajorOrMinor => console.log(isMajorOrMinor))

因此,您甚至可以有条件地在整个链条中操作数据。

但是,对我来说,最大的不同之一是map is typed。 这意味着如果您有一些数据,可以说:

interface IUser {
  name: string;
  age: number;
  dogs: IDog[];
}

你在某个时候收到一个用户,你想从他那里得到他的狗:

user$
  .map(user => user.dogs)
  .do(dogs => ...) // here, you do NOT need to precise (dogs: IDog[]) because Typescript will make a type inference

这就是为什么我总是使用地图,甚至只是“提取”一些数据。

【讨论】:

    【解决方案3】:

    停止使用 pluck!

    Pluck 现在计划在 RxJS v8 中删除。 你知道是什么原因吗?

    因为在JS中添加了optional chaining operator之后,本质上只是Map的弱版本。

    那么这两者有什么区别呢? 两者都用于“转换”将要发出的数据。 Map 可用于... 映射 可观察的发射(就像我们在 JS 中使用 Array.prototype.map 所做的那样),而 Pluck 用于选择/选择要发射的属性(不必发射我们不关心的属性,从而提高性能)。

    但即使在可选链接运算符之前,您也可以只映射属性而不是提取它们。结果和性能大致相同。

    pluck('prop')
    

    只是以下的简写:

    map(x => x.prop)
    

    那么,Pluck 的实现背后的原因是什么?

    它的实现基本上是为了实现路径遍历安全,这意味着如果未定义该属性,您可以尝试提取嵌套属性而不会出现错误(Map 会抛出):

    pluck('foo', 'bar', 'baz'); // no error if foo is not defined
    map(x => x.foo.bar.baz) // error if foo is not defined
    

    有了可选链,这个优势就不再存在了,因为我们可以这样做:

    map(x => x?.foo?.bar?.baz)
    

    这是 Pluck 运算符在未来将被弃用和删除的主要原因。 另一个重要的原因是用于 pluck 的 TS 类型非常复杂,并且没有 map 运算符那么健壮。

    GitHub 中获得了该信息: Pluck deprecation 的提交已经快一年了,但我仍然没有在文档中看到任何关于未来弃用的警告,因此我在这里发布,因为我认为这是一件好事。因为这个原因我已经停止采摘了。

    【讨论】:

      【解决方案4】:

      Map 可以对每个发出的值执行操作。 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-map https://www.learnrxjs.io/operators/transformation/map.html

      // value from observable = 10
      map(x => 10*x)
      // value from map = 100
      

      Pluck 只需选择每个发出值的嵌套属性之一。 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-pluck https://www.learnrxjs.io/operators/transformation/pluck.html

      // value from observable = {p = 10, w = 100}
      pluck('p')
      // value from pluck = 10
      

      【讨论】:

        【解决方案5】:

        它们非常相似,但据我了解,map 与数组一起使用,而 pluck 从对象中获取值。

        This is the place to go for specifics.

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-04
        • 2020-08-01
        • 1970-01-01
        • 2019-05-12
        • 1970-01-01
        • 2017-05-30
        • 2017-03-22
        • 2022-06-26
        相关资源
        最近更新 更多