dourunlao1642 2017-06-02 08:59
浏览 89
已采纳

如何在Julia中将husky()和in()函数与复杂的字典键一起使用?

haskey() and in() functions are very useful to test the content of dictionaries 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

but I was surprised by their behavior with complex keys :

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

What I did wrong ? Thank you very much for your comments !

Thanks to @Michael K. Borregaard, I can propose this solution :

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

But I have to store keys in a separate array. This means that can't warranty the unicity of the keys which is the strength of the dictionaries and why I choose to use it :(

So I have to use another step :

unique(keyArray)

Another better solution :

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

Compared to Julia, Go is more straightforward for this problem :

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"
  • 写回答

4条回答 默认 最新

  • doujing1156 2017-06-02 14:22
    关注

    You just need to teach your MyT type that you want it to consider equality in terms of its composite fields:

    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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作