PowerShell中能否将数组作为hashtable的键?如何引用对应键值?
问题原因
Hashtable对键的匹配逻辑依赖两个核心点:
- 键对象的
GetHashCode()方法返回的哈希值 - 键对象的
Equals()方法的相等判定结果
.NET中数组属于引用类型,默认的GetHashCode()和Equals()方法都是基于对象实例本身,而非数组内的元素内容。你每次调用@(1,2)都会在内存中生成一个全新的数组实例,哪怕两个数组的元素完全一致,它们的实例地址不同,哈希值也不同,因此Hashtable会把它们识别为完全不同的两个键,自然无法匹配到之前存入的值。
解决方案
方案1:复用同一数组实例操作
如果场景允许你留存存入时使用的数组实例,直接用这个实例作为键查询即可:
$h = @{} $key = @(1,2) $h[$key] = 'a' # 直接用留存的$key查询,可正常返回结果 $h[$key]
方案2:使用支持结构相等比较的字典替代普通Hashtable
如果需要按数组元素内容匹配键,可以使用支持自定义相等比较器的System.Collections.Generic.Dictionary,传入.NET内置的结构相等比较器,实现按元素内容匹配数组键:
# 初始化指定数组为键、字符串为值,使用结构相等比较器的字典 $dict = [System.Collections.Generic.Dictionary[object[], string]]::new([System.Collections.StructuralComparisons]::StructuralEqualityComparer) $dict[@(1,2)] = 'a' # 此时用新的同元素数组查询可正常返回结果 $dict[@(1,2)]
方案3:将数组转换为值类型的替代键
如果数组元素结构简单,可以把数组转成唯一标识元素内容的字符串、值元组等值类型作为键,避免引用匹配问题:
$h = @{} # 用分隔符拼接成字符串当键,注意分隔符不要出现在元素内容中 $keyStr = @(1,2) -join '|' $h[$keyStr] = 'a' # 查询时也做同样转换即可 $h[@(1,2) -join '|'] # PowerShell 7+也可以转成值元组,值元组默认按元素内容做相等判定 $keyTuple = [tuple]::Create(1,2) $h[$keyTuple] = 'a' $h[[tuple]::Create(1,2)]
内容的提问来源于stack exchange,提问作者lit
相关产品推荐
相关产品推荐

