Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 嵌套有序字典&;具有新对象的数组数据结构_Powershell_New Object - Fatal编程技术网

Powershell 嵌套有序字典&;具有新对象的数组数据结构

Powershell 嵌套有序字典&;具有新对象的数组数据结构,powershell,new-object,Powershell,New Object,我一直在开发一个嵌套的字典数据结构,以构建一个文件列表,以便在代码后面使用。目前,我正在使用它成功地创建空数据结构 $manageLocalAssets = @{ resources = @{ extra = New-Object Collections.ArrayList new = New-Object Collections.ArrayList skip = New-Object Colle

我一直在开发一个嵌套的字典数据结构,以构建一个文件列表,以便在代码后面使用。目前,我正在使用它成功地创建空数据结构

$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
        }
    }
两者都无法将哈希表强制转换为有序字典。我唯一的选择是这样丑陋的东西吗

$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
        }
    }
但它无法创建嵌套键、额外键、跳过键等。我是朝着正确的方向走,还是最好只允许一堆单独的新对象和添加线

编辑#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=newobjectcollections.Specialized.OrderedDictionary-property@{

所以,看起来额外的和新的都是在第一次处理中,然后skip在第一次分配中失败,资源在第二次分配中立即失败

编辑#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变量。似乎我还在寻找。

我想向后兼容性从来都不好?这是我能想到的最好的,有点接近结构ed定义(使用简单数组):

当然,您也可以将实际值(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))
)))

PS没有特别的支持<代码>有序字典< /代码>,所以不管你如何分割它,它都将继续是痛苦的。考虑有一个规则的哈希表,并通过对一个拥有键的属性进行跟踪,并仅对它进行枚举来扩展它;这样,你就可以得到两个世界最好的(排序)。。你可以用一个吃数组的小构造函数来包装它。@Jeroenmoster,我知道我没有本机支持,但我可以使用.NET类型。使用难看的方法来构建数据结构效果很好,而不用求助于本机哈希表和排序属性。这只是我想找到解决方案的难看的结构创建。最后,丑陋的结构和可读的用法似乎比优雅的结构和繁琐的用法要好,因为每次使用变量时,我都需要首先按属性进行排序。枚举
OrderedDictionary
Hashtable
会得到
KeyValuePair
s。我很少这样枚举它们,而是在
.Keys
,这在循环
.OrderedKeys
时同样有效。这假设您只构造一次,以后不添加新的键;如果是这样的情况,则吸引力要小得多。在这里使用
-Property
将不起作用,因为正如名称所示,这用于初始化对象的属性,而不是键。您也可以对有序循环执行此操作:
foreach($key-in(“extra”,“new”,…){$unordered[$key]}
这让我感到困惑,直到我意识到第一行是独立的,
开始了一个全新的管道。这让我感到困惑,因为我知道
OrderedDictionary
没有构造函数使用
IEnumerable
(很多集合类型都有)。我谦虚地建议插入一个换行符和/或将初始化转换为cmdlet,以提高可读性(和重用性)@JeroenMostert我想让它更简短,并尽可能多地保存行,同时仍然保留结构化键定义。我现在将该数组放入单独的变量中,希望这样能使它更可读。我不认为制作cmdlet是合适的,因为这是一种非常特殊的情况(ArrayList有两个级别)但我同意可以将其放入函数中。好吧,你可以通过这种方式使其递归并支持任意数量的级别(假设最低级别总是一个列表),但是的,这会变得更复杂。当我说“cmdlet”不过,我只是指一个本地函数,而不是放在模块中并普遍使用的函数。但是,是的,一个不使用
[CmdletBinding()]
的普通旧函数也可以。@Jeroenmoster我决定无论如何给出一个例子,谢谢。
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))
)))