mifan
2018 年10 月 3 日 03:57
1
遇到了好几次 Base.ht_keyindex2!
函数的调用,但是不清楚这个函数的用法,在 help
和 Google 中也没找到详细的解释说明
help?> Base.ht_keyindex2!
No documentation found.
Base.ht_keyindex2! is a Function.
# 1 method for generic function "ht_keyindex2!":
[1] ht_keyindex2!(h::Dict{K,V}, key) where {K, V} in Base at dict.jl:305
有人遇到过这个函数调用吗,可以解释一下这函数吗?
github 上搜了一下,找到了注释
# get the index where a key is stored, or -pos if not present
# and the key would be inserted at pos
# This version is for use by setindex! and get!
function ht_keyindex2!(h::Dict{K,V}, key) where V where K
—— julia/dict.jl at master · JuliaLang/julia
对比了下 ht_keyindex2!
与 ht_keyindex
的源码。在 key
不存在时,ht_keyindex
返回 -1
,而 ht_keyindex2!
使用 hashindex
取得 key 应当在的 index 位置,返回其相反数。
顺带测试了一下,这个函数并不会修改原哈希表(至少在 key 不存在时是这样),它带 !
后缀的原因是,用这个函数时,可能引起 rehash
操作 。依赖它实现的 setindex!
和 get!
则会修改原哈希表。
总之这个函数让 key 不存在时自动新增 key 变得方便了。
在 github 上搜的时候发现都是第三方库用得较多,一般是在实现特殊的哈希表,顺带实现相应的操作时(也就是写 julia 库),才会用到。
平常用 ht_keyindex
应该就够用了。 不用 getindex
大概是因为查询不存在的键时会报错。 口胡这两个函数目的不同
mifan
2018 年10 月 3 日 06:13
5
我就是读 JuAFEM (也是第三方的库) 时看到的,好几个地方用到的。可以解释一下 ht_keyindex
的用法吗? help
也没结果。
julia 哈希表的键值对分别存在两个 Array
里,所以会有相应的引索,ht_keyindex
就是用来取对应键的引索值,找不到就返回 -1
。
ht_keyindex2!
也差不多,只是在取不存在的键时,会返回那个键应在位置引索值的相反数 (真绕口,不如看源码 )
julia> h = Dict("A"=>1, "B"=>2)
Dict{String,Int64} with 2 entries:
"B" => 2
"A" => 1
julia> h.keys # 存放键的数组
16-element Array{String,1}:
#undef
"B"
"A"
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
julia> h.vals # 存放值的数组
16-element Array{Int64,1}:
244450080
2
1
244449856
244449856
244449856
244449856
244452208
244452208
244449856
244449856
244449856
244514840
244514840
244449856
257113136
julia> Base.ht_keyindex(h, "B") # 取 “B” 这个键在数组中的位置
2
julia> h.keys[2] # 验证一下
"B"
julia> Base.ht_keyindex(h, "C") # 不存在的键返回 -1
-1
ht_keyindex2!
接以上代码
看上去直接给 h.vals
与 h.keys
赋值并不能新增键值对。
键不存在时, ht_keyindex2!
返回的值会告诉你,插入对应的键会放在哪。(其实这里颠倒了因果,因为插入的位置就是根据 ht_keyindex2!
的返回值确定的,ref:julia/dict.jl at master · JuliaLang/julia )
julia> h.keys[4] = "C"
"C"
julia> h
Dict{String,Int64} with 2 entries:
"B" => 2
"A" => 1
julia> h.vals[4] = 3
3
julia> h
Dict{String,Int64} with 2 entries:
"B" => 2
"A" => 1
julia> h.vals
16-element Array{Int64,1}:
244450080
2
1
3
244449856
244449856
244449856
244452208
244452208
244449856
244449856
244449856
244514840
244514840
244449856
257113136
julia> h.keys
16-element Array{String,1}:
#undef
"B"
"A"
"C"
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
julia> Base.ht_keyindex2!(h, "C") # 如果有键 “C”,应该放在第 6 位
-6
julia> setindex!(h, 3, "C") # 插入键值对
Dict{String,Int64} with 3 entries:
"B" => 2
"A" => 1
"C" => 3
julia> h.keys # 检查效果
16-element Array{String,1}:
#undef
"B"
"A"
"C"
#undef
"C"
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
#undef
1 个赞
Roger
2018 年10 月 3 日 16:36
8
BTW,Base里面没有export的函数可能会break,用的时候需要注意