添加到Julia中的集合时重载对象比较? [英] Overload object comparison when adding to a set in Julia?

查看:16
本文介绍了添加到Julia中的集合时重载对象比较?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法重载 Base.Set 如何在 Julia 中进行对象比较?

Is there a way to overload how Base.Set does its object comparisons in Julia?

我尝试重载 isequal==,但我的对象本应相同时仍被标记为不同.

I tried overloading isequal and ==, but my objects are still marked as different when they should be the same.

例如

type Test
    x
    y
end

function ==(a::Test, b::Test)
    return a.x == b.x && a.y == b.y
end

Set([Test(2,3), Test(2,3)])

给予

Set([Test(2,3),Test(2,3)])

推荐答案

一个 Set 是一种 Dict 类型的值 Void:参考

A Set is a kind of Dict with values of type Void: ref

type Set{T} <: AbstractSet{T}
    dict::Dict{T,Void}

    Set() = new(Dict{T,Void}())
    Set(itr) = union!(new(Dict{T,Void}()), itr)
end  

Julia-lang 文档描述了 dic 输入如下:

Dict 是标准的关联集合.其实现使用hash() 作为键的散列函数, isequal() 确定平等.为自定义类型定义这两个函数以覆盖如何它们存储在哈希表中.

Dict is the standard associative collection. Its implementation uses hash() as the hashing function for the key, and isequal() to determine equality. Define these two functions for custom types to override how they are stored in a hash table.

检查,dict.jl,并寻找 ht_keyindex2()ht_keyindex() 函数.仅当这两个条件为 true 时,两者都将返回 index:

Check, dict.jl, and look for ht_keyindex2() and ht_keyindex() functions. Both will return an index only if these two conditions are true:

if !isslotmissing(h,index) && isequal(key,keys[index])
    return index
end

在上面的哪里:index = hashindex(key, sz)
Julia 使用 hash() 函数完成哈希的任务:

Where in the above: index = hashindex(key, sz)
Julia uses hash() function do the task of hashing:

hash(x[, h])
计算一个整数哈希码,使得 isequal(x,y)暗示哈希(x)==哈希(y).可选的第二个参数 h 是一个哈希代码与结果混合.新类型应该实现2 参数形式,通常通过调用 2 参数哈希方法递归地混合内容的哈希值(和 h).通常,任何实现散列的类型也应该实现自己的 == (因此是相等的)来保证属性上面提到过.

hash(x[, h])
Compute an integer hash code such that isequal(x,y) implies hash(x)==hash(y). The optional second argument h is a hash code to be mixed with the result. New types should implement the 2-argument form, typically by calling the 2-argument hash method recursively in order to mix hashes of the contents with each other (and with h). Typically, any type that implements hash should also implement its own == (hence isequal) to guarantee the property mentioned above.

因此,通过这些准备,很明显覆盖 Base.== 是不正确的 &完成任务的完整方法,但是

So with these preparations it is obvious that overriding Base.==, is not the right & complete way to do the task, but

  1. 我们需要重写 hash() 函数以返回相同的 hashindex
  2. 代替 Base.== 覆盖 Base.isequal
  3. 就足够了
  1. We need to override hash() function to return the same hashindex and
  2. Instead of Base.== it is sufficient to override Base.isequal

代码:

type Test
    x
    y
end

Base.hash(a::Test, h::UInt) = hash(a.y, hash(a.x, hash(:Test, h)))
Base.isequal(a::Test, b::Test) = Base.isequal(hash(a), hash(b))
Set([Test(2,3), Test(2,3)])

重点是,虽然 Test(2,3) == Test(2,3) #=>false 它按预期工作.

The point is, although Test(2,3) == Test(2,3) #=> false it works as expected.

这篇关于添加到Julia中的集合时重载对象比较?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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