我在powershell中使用hashtables / dictionaries有点麻烦。最新的包版是能够在有序字典中找到键的索引。
考虑以下示例:
$dictionary = [Ordered]@{
'a' = 'blue';
'b'='green';
'c'='red'
}
如果这是一个普通的数组,我可以使用IndexOf()来查找条目的索引。
[array]::IndexOf($dictionary,'c').
在正常情况下,这将返回2.
如果我尝试使用有序字典,我会得-1。
任何解决方案?
编辑: 如果有人读到这个想知道我在说什么。我试图用它来创建一个对象,以一种也有数字顺序的方式规范化属性条目。
我试图将此用于进程的状态,例如:
$_processState = [Ordered]@{
'error' = 'error'
'none' = 'none'
'started' = 'started'
'paused' = 'paused'
'cleanup' = 'cleanup'
'complete' = 'complete'
}
如果你能够轻松地做到这一点,上面的对象会给$_processState.error
一个索引值0并在每个条目中上升,最后给$_processState.complete
一个索引值5.然后如果你比较两个属性,通过“索引值”,您可以看到哪一个是简单的运算符。例如:
$thisObject.Status = $_processState.complete
If ($thisObject.Status -ge $_processState.cleanup) {Write-Host 'All done!'}
PS > All done!
^^不能正常工作,但这就是主意。这就是我的目标。或者也许找到像$ _processState.complete.IndexNumber()
这样的东西拥有这样的对象还允许您通过索引名称本身分配值,同时标准化选项......
$thisObject.Status = $_processState.paused
$thisObject.Status
PS > paused
当时并不确定这是最好的方法,或者它仍然是PS v5中提供的所有自定义类选项的最佳方法。
答案 0 :(得分:3)
它可能没有比Frode F.的答案更有效,但也许更简洁(内联)只是将哈希表的keys
集合放在子表达式中{{1然后在结果上调用indexOf。
您的具体表达方式很简单:
$()
...按预期给出值$($dictionary.keys).indexOf('c')
。这也适用于常规哈希表...除非哈希表几乎以任何方式被修改,当然......所以它在这种情况下可能不是很有用。
使用此哈希表(其中还显示了编码2
的许多方法...):
4
将产生以下表达式/结果对:
$hashtable = [ordered]@{
sample = 'hash table'
0 = 'hello'
1 = 'goodbye'
[char]'4' = 'the ansi character 4 (code 52)'
[char]4 = 'the ansi character code 4'
[int]4 = 'the integer 4'
'4' = 'a string containing only the character 4'
5 = "nothing of importance"
}
顺便说一下:
# Expression Result
#------------------------------------- -------------
$($hashtable.keys).indexof('5') -1
$($hashtable.keys).indexof(5) 7
$($hashtable.keys).indexof('4') 6
$($hashtable.keys).indexof([char]4) 4
$($hashtable.keys).indexof([int]4) 5
$($hashtable.keys).indexof([char]'4') 3
$($hashtable.keys).indexof([int][char]'4') -1
$($hashtable.keys).indexof('sample') 0
等于[int][char]'4'
[int]52
有"值" [char]'4'
的(幅度?),但是是一个字符,因此它被用作...必须喜欢打字系统,如果你不小心的话,它虽然很灵活,但有时会变得非常糟糕。
答案 1 :(得分:2)
字典使用键而不是索引。 OrderedDictionary结合了hashtable
和ArrayList
来为字典提供顺序/索引支持,但它仍然是字典(基于密钥)的集合。
如果需要获取OrderedDictionary
(或hasthable
)中对象的索引,则需要使用foreach-loop和计数器。示例(应该作为函数创建):
$hashTable = [Ordered]@{
'a' = 'blue';
'b'='green';
'c'='red'
}
$i = 0
foreach($key in $hashTable.Keys) {
if($key -eq "c") { $i; break }
else { $i++ }
}
这也是它的内部工作原理。您可以在.NET Reference Source
中阅读OrderedDictionary
的{{1}}方法的源代码来验证这一点
答案 2 :(得分:0)
对于我试图解决的初始问题,一个类似的进程状态,您现在可以使用从PowerShell v5开始的枚举。
使用Enum关键字,按名称设置枚举数,并为它们提供整数值。值可以是任何值,但我在此示例中使用以0开头的升序值:
Enum _ProcessState{
Error = 0
None = 1
Started = 2
Paused = 3
Cleanup = 4
Complete = 5
Verified = 6
}
#the leading _ for the Enum is just cosmetic & not required
创建枚举后,您可以将其分配给变量。变量的内容将返回Enum的文本名称,您可以将它们比作整数。
$Item1_State = [_ProcessState]::Started
$Item2_State = [_ProcessState]::Cleanup
#return state of second variable
$Item2_state
#comparison
$Item1_State -gt $Item2_State
将返回:
Cleanup
False
如果你想比较并返回最高:
#sort the two objects, then return the first result (should return the item with the largest enum int)
$results = ($Item1_State,$Item2_State | Sort-Object -Descending)
$results[0]
有趣的是,您也可以对它们使用算术,例如:
$Item1_State + 1
$Item1_State + $Item2_State
将返回:
Paused
Verified
有关Enum的更多信息: