使用 RxJs groupBy 将对象作为键 [英] Using RxJs groupBy with objects as keys

查看:48
本文介绍了使用 RxJs groupBy 将对象作为键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 groupBy 与 RxJs 一起使用,并且我需要使用对象作为键.如果我不这样做并且我使用,例如,像这样的简单字符串:

I'm trying to use groupBy with RxJs, and I need to use objects as keys. If I don't and I use, for example, simple strings like this:

var types = stream.groupBy(
    function (e) { return e.x; }); //x is a string

然后一切顺利,我的订阅被调用一次,并且只为每个不同的键调用一次.但是,如果我尝试使用对象,则会为 stream 中的每个元素调用订阅,即使键恰好与之前的键相同.

then everything goes fine and my subscription is called once, and once only, for each different key. But if I try with objects, the subscription is called for each element from stream, even if a key happens to be the same as previous ones.

当然有一个关于对象相等的问题,但这是我感到困惑的地方,因为我不明白如何使用 groupBy 的附加参数.最新版本的文档说有第三个参数可以是 比较器,但它永远不会被调用.早期的文档讨论了 key serializer 这是一个完全不同的想法,但两种方法都不适合我.

There is of course a problem about object equality, but this is where I get confused because I don't understant how to use the additional arguments for groupBy. The latest version of docs says there have a 3rd argument that can be a comparer, but it never gets called. Earlier docs talk about a key serializer which is a totally different idea, but neither ways work for me.

查看 Rx 源代码,我看到尝试检查 getHashCode 函数,但我没有找到有关它的文档.代码如下:

Looking at Rx source code, I see attempts to check for a getHashCode function, but I do not find and documentation about it. Code like this:

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?

就是我要写的东西,但运气不好,我为第三个回调所做的一切都没有被调用.

is what i'm trying to write, but no luck, and whatever I put for the 3rd callback is not called.

这里出了什么问题?

推荐答案

最简单的解决方案是确保您的键函数返回一个数字或字符串.但是如果你真的想返回一个对象作为你的键,那么你可以使用 comparerhashCode 来帮助 groupBy.您可以使用 valueOf 而不是 hashCode(它要求您返回一个数字),它可以让您返回一个字符串.

The simplest solution is to make sure your key function returns a number or string. But if you really want to return an object as your key, then you can use comparer and hashCode to help groupBy. Instead of hashCode (which requires you return a number), you can use valueOf which lets you return a string.

hashCodevalueOf 的工作方式应该类似于 c# Object.GetHashCode.

hashCode and valueOf should work similar to the c# Object.GetHashCode.

他们应该返回一个这样的值:

They should return a value such that:

  • 被认为相等的两个键应该每次都返回相同的值.
  • 被认为不相等的两个键通常应该返回不同的值(以尽量减少冲突).您越能确保这一点,词典的效率就会越高.

区别在于hashCode 应该返回一个数字,而valueOf 可以返回一个数字或一个字符串.因此 valueOf 更容易实现.

The difference is hashCode should return a number and valueOf can return a number or a string. Thus valueOf is easier to implement.

comparer 的规则是它需要 2 个键值,并且应该返回 true 表示相等,false 表示不相等.

The rules for the comparer is that it takes 2 key values and should return true to indicate equality and false to indicate inequality.

因此,您可以将示例编写为:

So, you might write your example as:

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 函数实际上产生了与您的比较器匹配的唯一值,并且您并不真正关心键是否作为实际对象向下游传输,那么只需让您的生活更轻松,将您的密钥转换为字符串并像这样使用字符串密钥:

But if your valueOf function is actually producing unique values that match your comparer and you don't really care about whether the key is tramsitted downstream as an actual object, then just make your life easier and transform your key into a string and use a string key like so:

var types = stream.groupBy(
    function (e) { return JSON.stringify({ x: e.x, y: e.y }); },
    function (e) { return e; });

这篇关于使用 RxJs groupBy 将对象作为键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆