我一直在开发嵌套的字典数据结构,以构建文件列表,以供稍后在代码中使用。目前,我正在成功地使用它来创建空的数据结构。
$manageLocalAssets = @{
resources = @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
definitions = @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
}
这可行,但是我想使用有序词典而不是哈希表,因此我可以按定义的顺序遍历数据。另外,我需要支持PS2.0(不要问),所以我不能使用[ordered]类型。
我尝试过
[Collections.Specialized.OrderedDictionary]$manageLocalAssets = @{
resources = @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
definitions = @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
}
我已经尝试过
$manageLocalAssets = [Collections.Specialized.OrderedDictionary]@{
resources = @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
definitions = @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
}
都无法将哈希表转换为有序字典。我唯一的选择是这样的丑陋(IMO)
$manageLocalAssets = New-Object Collections.Specialized.OrderedDictionary
$manageLocalAssets.Add('resources', (New-Object Collections.Specialized.OrderedDictionary))
$manageLocalAssets.resources.Add('extra', (New-Object Collections.ArrayList))
[ss64] [1]让我想到-财产可能是答案,这似乎很接近
$manageLocalAssets = New-Object Collections.Specialized.OrderedDictionary -property @{
resources = New-Object Collections.Specialized.OrderedDictionary -property @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
definitions = New-Object Collections.Specialized.OrderedDictionary -property @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
}
但是它无法创建嵌套键,额外键,跳过键等。我朝着正确的方向前进,还是我最好只接受一堆单独的New-Object和.Add行?
编辑#1:我有一个想法,因为从最深层次上讲,数据结构是相同的,所以我尝试了
$assets = New-Object Collections.Specialized.OrderedDictionary -property @{
extra = New-Object Collections.ArrayList
new = New-Object Collections.ArrayList
skip = New-Object Collections.ArrayList
update = New-Object Collections.ArrayList
}
$manageLocalAssets = New-Object Collections.Specialized.OrderedDictionary -property @{
resources = $assets
definitions = $assets
}
奇怪的是,错误是
New-Object : The member "skip" was not found for the specified .NET object.
At \\Mac\Support\Px Tools\Dev 4.0\Resources\PxContext_Machine.ps1:413 char:15
+ ... $assets = New-Object Collections.Specialized.OrderedDictionary -pro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.NewObjectCommand
New-Object : The member "resources" was not found for the specified .NET object.
At \\Mac\Support\Px Tools\Dev 4.0\Resources\PxContext_Machine.ps1:419 char:26
+ ... calAssets = New-Object Collections.Specialized.OrderedDictionary -pro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.NewObjectCommand
[1]: https://ss64.com/ps/new-object.html
413 是$assets = New-Object Collections.Specialized.OrderedDictionary -property @{
行,而
419 是$manageLocalAssets = New-Object Collections.Specialized.OrderedDictionary -property @{
行。
因此,似乎首先要处理多余的内容和新内容,然后在第一个任务中跳过失败,而在第二个任务中资源立即失效。
编辑#2:因此,将重复部分分解为不同的变量会使我想到这一点
$assets = New-Object Collections.Specialized.OrderedDictionary
$assets.Add('extra', (New-Object Collections.ArrayList))
$assets.Add('new', (New-Object Collections.ArrayList))
$assets.Add('skip', (New-Object Collections.ArrayList))
$assets.Add('update', (New-Object Collections.ArrayList))
$manageLocalAssets = New-Object Collections.Specialized.OrderedDictionary
$manageLocalAssets.Add('resources', $assets)
$manageLocalAssets.Add('definitions', $assets)
实际上,这是更少的行,并且当我添加到$ manageLocalAssets时,效率会更高。它在外观上看起来不像我的其他数据结构初始化,但是我想我很快就会习惯这一点。而且它使我可以使用这样的循环结构以所需的顺序处理数据。
foreach ($asset in $manageLocalAssets.keys) {
foreach ($key in ($manageLocalAssets.$asset).keys) {
Write-Host "$asset $key"
foreach ($file in $manageLocalAssets.$asset.$key) {
Write-Host " $file"
}
}
}
这不是“理想”,但理想状态在这里意味着“熟悉”,这不是做出决定的重要理由。
编辑#3:不。我错了。实际上,这会使$manageLocalAssets.resources
和$manageLocalAssets.definitions
的内容相同,即$ assets变量。似乎我还在寻找。
答案 0 :(得分:1)
我认为向后兼容永远不会很漂亮?这是我能想到的最好的方法,有点接近结构化定义(使用简单数组):
$definition = ((
"resources", (
"extra",
"new",
"skip",
"update"
)), (
"definitions", (
"extra",
"new",
"skip",
"update"
)))
$manageLocalAssets = New-Object System.Collections.Specialized.OrderedDictionary
$definition | foreach {
$sub = New-Object System.Collections.Specialized.OrderedDictionary
$_[1] | foreach {
$sub.Add($_, (New-Object Collections.ArrayList))
}
$manageLocalAssets.Add($_[0], $sub)
}
当然,您也可以将实际值(ArrayList)放入数组定义中,但是我想那会写很多东西,而且看起来也不漂亮。
替代解决方案,使用函数从定义中创建具有可变级别的有序字典。较为冗长但可重复使用:
function New-OrderedDictionary ($definition) {
$dict = New-Object System.Collections.Specialized.OrderedDictionary
foreach ($item in $definition) {
$key, $value = $item[0, 1]
# you might want to change this check,
# depending on how you want to built the definition
if ($value.Count -gt 0) {
$value = New-OrderedDictionary $value
}
$dict.Add($key, $value)
}
return $dict
}
$manageLocalAssets = New-OrderedDictionary ((
"resources", (
("extra" , (New-Object System.Collections.Specialized.OrderedDictionary)),
("new" , (New-Object System.Collections.Specialized.OrderedDictionary)),
("skip" , (New-Object System.Collections.Specialized.OrderedDictionary)),
("update", (New-Object System.Collections.Specialized.OrderedDictionary))
)), (
"definitions", (
("extra" , (New-Object System.Collections.Specialized.OrderedDictionary)),
("new" , (New-Object System.Collections.Specialized.OrderedDictionary)),
("skip" , (New-Object System.Collections.Specialized.OrderedDictionary)),
("update", (New-Object System.Collections.Specialized.OrderedDictionary))
)))