cze*_*rny 142 javascript set ecmascript-harmony
新的ES 6(Harmony)引入了新的Set对象.Set使用的身份算法类似于===运算符,因此不太适合比较对象:
var set = new Set();
set.add({a:1});
set.add({a:1});
console.log([...set.values()]); // Array [ Object, Object ]
Run Code Online (Sandbox Code Playgroud)
如何自定义Set对象的相等性以进行深层对象比较?有没有像Java这样的东西equals(Object)?
jfr*_*d00 94
ES6 Set对象没有任何比较方法或自定义比较可扩展性.
的.has(),.add()而.delete()方法只关闭它是一个基本相同的实际物体或相同的值,不必插入或更换只是逻辑的手段.
你可能从a Set和replace中派生你自己的对象.has(),.add()并且首先.delete()用一些深层对象进行比较的方法来查找该项是否已经在Set中,但是由于底层Set对象没有帮助,性能可能不会很好一点都不 在调用原始对象之前,您可能只需要对所有现有对象进行强力迭代,以使用您自己的自定义比较查找匹配项.add().
5.2为什么我不能配置映射和集合比较键和值的方式?
问题:如果有一种方法可以配置哪些映射键和哪些集合元素被认为是相等的,那就太好了.为什么不存在?
答:该功能已被推迟,因为难以正确有效地实施.一种选择是将回调交给指定相等的集合.
Java中提供的另一个选项是通过对象实现的方法(Java中的equals())指定相等性.但是,这种方法对于可变对象是有问题的:通常,如果对象发生更改,其集合内的"位置"也必须更改.但这不是Java中发生的事情.JavaScript可能会更安全,只能通过值对特殊的不可变对象(所谓的值对象)进行比较.按值比较意味着如果两个值的内容相等,则认为它们相等.原始值在JavaScript中按值进行比较.
cze*_*rny 27
正如在jfriend00中提到的那样,平等关系的定制可能是不可能的.
下面的代码概述了计算效率(但内存昂贵)的解决方法:
class GeneralSet {
constructor() {
this.map = new Map();
this[Symbol.iterator] = this.values;
}
add(item) {
this.map.set(item.toIdString(), item);
}
values() {
return this.map.values();
}
delete(item) {
return this.map.delete(item.toIdString());
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
每个inserted元素都必须实现toIdString()返回string的方法.当且仅当它们的toIdString方法返回相同的值时,才认为两个对象是相等的.
Rus*_*vis 16
正如顶级答案所提到的,对于可变对象,自定义相等性是有问题的。好消息是(我很惊讶还没有人提到这一点)有一个非常流行的库,称为immutable-js,它提供了一组丰富的不可变类型,这些类型提供了您正在寻找的深层值相等语义。
这是您使用immutable-js 的示例:
const { Map, Set } = require('immutable');
var set = new Set();
set = set.add(Map({a:1}));
set = set.add(Map({a:1}));
console.log([...set.values()]); // [Map {"a" => 1}]
Run Code Online (Sandbox Code Playgroud)
也许您可以尝试使用JSON.stringify()进行深度对象比较。
例如 :
const arr = [
{name:'a', value:10},
{name:'a', value:20},
{name:'a', value:20},
{name:'b', value:30},
{name:'b', value:40},
{name:'b', value:40}
];
const names = new Set();
const result = arr.filter(
item => !names.has(JSON.stringify(item))
? names.add(JSON.stringify(item))
: false
);
console.log(result);Run Code Online (Sandbox Code Playgroud)
为了补充这里的答案,我继续实现了一个 Map 包装器,它采用自定义哈希函数、自定义相等函数,并在存储桶中存储具有等效(自定义)哈希值的不同值。
可以预见,结果证明它比czerny 的字符串连接方法慢。
完整来源:https : //github.com/makoConstruct/ValueMap
| 归档时间: |
|
| 查看次数: |
31425 次 |
| 最近记录: |