javascript - RxJs 简化了重复的 pluck + flatMap
问题描述
从这样的对象开始:
const business = {
id: "1a2b3c",
accounts: [
{
name: "Pizza Express",
stores: [
{ id: "5", webSite: "www.pizza-ny.com" },
{ id: "6", webSite: "www.pizza-la.com" }
]
}
]
};
预期输出:商店流(不是商店数组)
我的尝试:
return business.pipe(
pluck("accounts"),
flatMap(val => val),
pluck("stores"),
flatMap(val => val)
);
这行得通,但对我来说,运算符似乎是重复的,我想知道我是否可以简化它们。也尝试了常见的map
,但我无法得到它。
例如:
return business.pipe(
pluck("accounts"),
map(val => val.stores)
);
我不明白为什么这会返回undefined
。我得到一个数组,accounts
然后投影stores
每个属性......我想我误解了一些东西。
你看到更简单或更优雅的方法了吗?
解决方案
由于您正在访问嵌套数组的嵌套对象,因此您的运算符中会有一些重复。可能有一种方法可以编写一个不错的自定义运算符(如果我有时间,也许我会研究一下),但我认为最简单的方法是只使用mergeMap(与 相同的东西flatMap
)。
它看起来像这样(编辑以过滤掉没有商店的帐户 - 归功于 Picci 的评论)
import { of } from "rxjs";
import { mergeMap, filter } from "rxjs/operators";
of(business)
.pipe(
mergeMap(b => b.accounts),
/* filter out accounts that don't have stores */
filter(a => !!a.stores),
mergeMap(a => a.stores)
)
.subscribe(console.log);
/** console output:
*
* { id: "5", webSite: "www.pizza-ny.com" }
* { id: "6", webSite: "www.pizza-la.com" }
*/
这是堆栈闪电战:https ://stackblitz.com/edit/rxjs-njvj7q?devtoolsheight=33&file=index.ts
旁注:您甚至可以使用switchMap()而不是mergeMap()
. 由于您正在处理完整的可观察对象,因此您使用哪一个之间没有太大区别。
编辑(map
差异解释)
您的 map() 不工作的原因是因为您试图访问数组上的 .stores,而不是对象:
return business.pipe(
pluck("accounts"), // accounts is an array
map(val => val.stores) // `accounts[0].stores` would return a value for you
);
map
Array.prototype.map()
和 RxJS之间的工作方式不同,map()
因为 RxJS 有不同的实现。
在普通的 JavaScript 中map()是一个数组上的函数,将返回一个新的数组。关键是它始终是基于数组的。从文档(强调添加):
该
map()
方法创建一个新数组,其中填充了对调用数组中的每个元素调用提供的函数的结果。
在 RxJS 中, map()是一个运算符,应用于Observable中的任何值。它不保证是一个数组,因此它不会迭代该值。RxJSmap()
正在获取Observable内部的值并将其“映射”到新的结构/值。从文档(强调添加):
将给定
project
函数应用于源 Observable 发出的每个值,并将结果值作为 Observable 发出。
推荐阅读
- spring - 如何使用 @MockBean 和 MockMvc 将一些带有 HTTP POST 的数据附加到模拟存储库
- reactjs - 当父状态更改时,React 子组件不会重新渲染
- android - 添加插件时出错 plugin.google.maps.CordovaGoogleMaps
- r - R Shiny - 隔离使用 req() 检查前置条件的反应式表达式
- flutter - Flutter:过滤ListView时删除重复项
- java - 所有 JPA 规范查询之间的 AND 操作
- python - Python正则表达式循环跳过每三个项目
- openssl - 使用存储在 Yubikey 上的 CA 对证书签名请求进行签名
- ios - 如何使用 Twilio 可编程视频 SDK 在 iOS 上将用户配对
- ios - 如何使用 AWS 推送通知服务修复未注册或过期令牌错误