如何在Julia中使用haskey()和in()函数以及复杂的字典键?

Fre*_*red 3 struct dictionary go julia

haskey()和in()函数对于测试Julia中的字典内容非常有用:

julia> dict = Dict("a" => 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5)
Dict{String,Int64} with 5 entries:
  "c" => 3
  "e" => 5
  "b" => 2
  "a" => 1
  "d" => 4

julia> haskey(dict, "a")
true

julia> in(("a" => 1), dict)
true
Run Code Online (Sandbox Code Playgroud)

但他对复杂键的行为感到惊讶:

julia> immutable MyT
           A::String
           B::Int64
       end

julia> a = Dict(MyT("Tom",191)=>1,MyT("Bob",20)=>1,MyT("Jo",315)=>1,MyT("Luc",493)=>1)
Dict{MyT,Int64} with 4 entries:
  MyT("Tom",191) => 1
  MyT("Jo",315)  => 1
  MyT("Bob",20)  => 1
  MyT("Luc",493) => 1

julia> keys(a)
Base.KeyIterator for a Dict{MyT,Int64} with 4 entries. Keys:
  MyT("Tom",191)
  MyT("Jo",315)
  MyT("Bob",20)
  MyT("Luc",493)

julia> haskey(a, MyT("Tom",191))
false

julia> in((MyT("Tom",191) => 1), a)
false
Run Code Online (Sandbox Code Playgroud)

我做错了什么?非常感谢您的评论!

感谢@Michael K. Borregaard,我可以提出这个解决方案:

a = Dict{MyT, Int64}()

keyArray = Array{MyT,1}()
keyArray = [MyT("Tom",191),MyT("Bob",20),MyT("Jo",315),MyT("Luc",493)]

for i in keyArray
    a[i] = 1
end

println(a)
# Dict(MyT("Tom",191)=>1,MyT("Tom",191)=>1,MyT("Luc",493)=>1,MyT("Jo",315)=>1,MyT("Luc",493)=>1,MyT("Bob",20)=>1,MyT("Jo",315)=>1,MyT("Bob",20)=>1)

keyArray[1]            # MyT("Tom",191)
haskey(a, keyArray[1]) # true
Run Code Online (Sandbox Code Playgroud)

但我必须将密钥存储在一个单独的数组中.这意味着不能保证键的唯一性,这是词典的力量和我选择使用它的原因:(

所以我必须使用另一个步骤:

unique(keyArray)
Run Code Online (Sandbox Code Playgroud)

另一个更好的解

function CompareKeys(k1::MyT, k2::MyT)
    if k1.A == k2.A &&  k1.B == k2.B
        return true
    else 
        return false
    end
end

function ExistKey(k::MyT, d::Dict{MyT, Int64})
    for i in keys(d)
        if CompareKeys(k, i)
            return true
        end
    end
    return false
end

a = Dict(MyT("Tom",191)=>1,MyT("Bob",20)=>1,MyT("Jo",315)=>1,MyT("Luc",493)=>1)

ExistKey(MyT("Tom",192),a) # false

ExistKey(MyT("Tom",191),a) # true
Run Code Online (Sandbox Code Playgroud)

与Julia相比,Go更容易解决这个问题:

package main

import (
    "fmt"
)

type MyT struct {
    A string
    B int
}

func main() {

    dic := map[MyT]int{MyT{"Bob", 10}: 1, MyT{"Jo", 21}: 1}

    if _, ok := dic[MyT{"Bob", 10}]; ok {
        fmt.Println("key exists")
    }
}
// answer is "key exists"
Run Code Online (Sandbox Code Playgroud)

Mat*_* B. 6

你只需要教你的MyT类型,你希望它在复合字段方面考虑相等:

julia> immutable MyT
           A::String
           B::Int64
       end
       import Base: ==, hash
       ==(x::MyT, y::MyT) = x.A == y.A && x.B == y.B
       hash(x::MyT, h::UInt) = hash(x.A, hash(x.B, hash(0x7d6979235cb005d0, h)))

julia> a = Dict(MyT("Tom",191)=>1,MyT("Bob",20)=>1,MyT("Jo",315)=>1,MyT("Luc",493)=>1)
Dict{MyT,Int64} with 4 entries:
  MyT("Jo", 315)  => 1
  MyT("Luc", 493) => 1
  MyT("Tom", 191) => 1
  MyT("Bob", 20)  => 1

julia> haskey(a, MyT("Tom",191))
true

julia> in((MyT("Tom",191) => 1), a)
true
Run Code Online (Sandbox Code Playgroud)