使用 RxJs groupBy 将对象作为键
Using RxJs groupBy with objects as keys
我正在尝试将groupBy
与RxJs一起使用,我需要将对象用作键。如果我不这样做,例如,我使用像这样的简单字符串:
var types = stream.groupBy(
function (e) { return e.x; }); //x is a string
然后一切顺利,我的订阅被调用一次,并且只调用一次,用于每个不同的密钥。但是如果我尝试使用对象,则会为 stream
中的每个元素调用订阅,即使键恰好与以前的键相同。
当然,对象相等性存在问题,但这就是我感到困惑的地方,因为我不明白如何使用额外的参数来groupBy
。最新版本的文档说有第三个参数可以作为比较器,但它从未被调用。早期的文档谈到了一个密钥序列化程序,这是一个完全不同的想法,但这两种方法都不适合我。
查看 Rx 源代码,我看到尝试检查getHashCode
函数,但我没有找到和文档。像这样编写代码:
var types = stream.groupBy(
function (e) {
return { x: e.x, y: e.y }; //is this valid at all?
},
function (e) { return e; },
function (...) { return ???; }); //what am I supposed to do here?
是我想写的,但没有运气,我为第三个回调放的任何内容都没有被调用。
这是怎么回事?
最简单的解决方案是确保键函数返回数字或字符串。 但是如果你真的想返回一个对象作为你的键,那么你可以使用comparer
和hashCode
来帮助groupBy
。 您可以使用 valueOf
来返回字符串,而不是 hashCode
(这需要您返回一个数字)。
hashCode
和valueOf
的工作方式应该类似于 c# Object.GetHashCode。
它们应返回一个值,以便:
- 被视为相等的两个键每次都应返回相同的值。
- 被视为不相等的两个键通常应返回不同的值(以最大程度地减少冲突)。 您越能确保这一点,字典的效率就越高。
区别在于hashCode
应该返回一个数字,而valueOf
可以返回一个数字或一个字符串。 因此valueOf
更容易实现。
comparer
的规则是它需要 2 个键值,并应返回 true
以指示相等,false
以指示不平等。
因此,您可以将示例编写为:
var valueOf = function () {
return JSON.stringify(this);
};
var keyCompare = function (a, b) { return a.x === b.x && a.y === b.y; };
var types = stream.groupBy(
function (e) {
return { x: e.x, y: e.y, valueOf: valueOf }; //is this valid at all?
},
function (e) { return e; },
keyCompare);
但是,如果你的valueOf
函数实际上正在生成与你的比较器匹配的唯一值,并且你并不真正关心键是否作为实际对象被放置在下游,那么只需让你的生活更轻松,并将你的键转换为字符串并使用字符串键,如下所示:
var types = stream.groupBy(
function (e) { return JSON.stringify({ x: e.x, y: e.y }); },
function (e) { return e; });
- 如何使用(this)访问Angular 2 http rxjs catch函数中的对象属性
- 使用rxjs创建一个可观察的对象,该对象稍后将连接到web套接字
- RxJs-具有可观测属性的平面图对象
- 使用 RxJs groupBy 将对象作为键
- 在触发观察对象上执行对某些观察对象的操作- RxJS
- 在为RXJS可观察对象编写测试时,如何避免通过业务逻辑传递调度器?
- 带有大对象元素数组的Rxjs后端循环带有observable
- 错误在RxJs中被认为是来自可观察对象的发射吗?
- 用RxJS过滤对象的对象
- Angular 2 rxjs的嵌套观察对象
- RXJS对可观察对象的转换方法同步或异步运行
- 如何将promise序列转换为Rx.用RxJS观察对象
- Rxjs如何知道可观察对象有多少订阅者
- Rxjs观察对象的更新和变化
- 我如何暂停一个RxJS缓冲的可观察对象基于在缓冲区中的值,因为他们被评估
- 如何判断一个可观察对象是否在“等待”另一个使用RxJS(例如,用于Ajax请求指示符)
- 如何使用RxJS操作符创建一个可观察的自定义对象流
- 用RxJS合并未知数量的可观察对象
- 如何为RxJS Observable中的每个发射创建一个新对象
- 在高阶rxjs可观察对象中收集当前不完整的可观察对象