简体   繁体   English

如何使用用户定义的相等函数在Javascript中创建一组用户定义的对象?

[英]How to create a Set of user-defined objects in Javascript with a user-defined equality function?

I am very new to Javascript and wondering if it is possible to create a Set of user-defined objects in a way that allows me to specify the function that is used to make equality comparisons? 我是Javascript的新手,想知道是否有可能以允许我指定用于进行相等比较的函数的方式创建一组用户定义的对象?

Here's a contrived example just to illustrate the functionality that I'm looking for: 这是一个人为的例子,只是为了说明我正在寻找的功能:

myClass = function(val){
                 var self = this;
                 self.val = val
                 self.equals = //used defined equals function 
           }

a = new myClass(1.0)
b = new myClass(2.0)
c = new myClass(2.0)

s = new Set() //does not have to be actual "Set"
s.add(a)
s.add(b)
s.add(c)

s.size === 2 //returns true
s.has(a) //returns true
s.has(b) //returns true
s.has(c) //returns true

I've found Set implementations (like this one ), but it seems like are only designed for values, not user-defined objects. 我发现了Set实现(就像这个 ),但它似乎只是为值设计,而不是用户定义的对象。 I suspect that there are other implementations that use === but this would not be useful in my case since I don't believe that I can override === either. 我怀疑还有其他实现使用===但这在我的情况下没用,因为我不相信我可以覆盖===

My question is very similar to this question . 我的问题与这个问题非常相似。 I'm posting it again since: a) I don't necessarily need a native ES6 solution and would be open to using a third party library. 我之后再次发布它:a)我不一定需要本机ES6解决方案,并且可以使用第三方库。 and b) it's been some time since that question was posted. b)这个问题发布后已经有一段时间了。

If you would accept to work with/override valueOf , then you could proceed like this: 如果您接受使用/覆盖valueOf ,那么您可以这样继续:

 // Implementation of special Set: function mySet() { var self = this; self.size = 0; // Use a private map that will be keyed by the valueOf() of each added item: var map = new Map(); self.add = function (item) { map.set(item.valueOf(), item); self.size = map.size; }; self.has = function (item) { return map.has(item.valueOf()); }; self[Symbol.iterator] = function* () { for (var pair of map) { yield pair[1]; // return the item ( not the valueOf() in [0]) } }; // etc... } // Test code: myClass = function(val){ var self = this; self.val = val; self.valueOf = function () { return self.val; }; } a = new myClass(1.0); b = new myClass(2.0); c = new myClass(2.0); s = new mySet(); //does not have to be actual "Set" s.add(a); s.add(b); s.add(c); document.write('size: ' + s.size + '<br>'); document.write('has(a): ' + s.has(a) + '<br>'); document.write('has(b): ' + s.has(b) + '<br>'); document.write('has(c): ' + s.has(c) + '<br>'); for (item of s) { document.write('stored item: ' + JSON.stringify(item) + '<br>'); }; 

Edit 编辑

Months later, I answered a similar question , where I did not suggest the use of valueOf , but a function that could be provided to the MySet constructor, defaulting to JSON.stringify . 几个月后, 我回答了一个类似的问题 ,我没有建议使用valueOf ,而是一个可以提供给MySet构造函数的函数,默认为JSON.stringify

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM