为什么我不能在一个arraylist中存储哈希表?

时间:2017-07-21 16:00:29

标签: loops powershell arraylist hashtable

这是我的代码

$allTests = New-Object System.Collections.ArrayList
$singleTest = @{}

$singleTest.add("Type", "Human")

1..10 | foreach {

    $singleTest.add("Count", $_)
    $singleTest.add("Name", "FooBar...whatever..$_")
    $singleTest.add("Age", $_)
    $allTests.Add($singleTest) | out-null

    $singleTest.remove("Count")
    $singleTest.remove("Name")
    $singleTest.remove("Age")
}

根据我的理解,我的循环应该是每次到达时都会将哈希表的副本添加到arraylist

$allTests.Add($singleTest) | out-null

循环继续,删除一些键,这为循环的下一次迭代铺平了道路。这不是发生的事情,它就像add命令只是添加对哈希表的引用。

如果我检查

的最终值
$allTests

返回

Name                           Value                                                                                                                   
----                           -----                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human                                                                                                                   
Type                           Human     

如何修复此问题,以便哈希表的实际副本存储在数组列表中?

我正在寻找像

这样的输出
$allTests[0]

Name                           Value                                                                                                                   
----                           -----                                                                                                                   
Count                          1                                                                                                                       
Name                           FooBar...whatever..1                                                                                                    
Age                            1                                                                                                                       
Type                           Human  

$allTests[1]   

Name                           Value                                                                                                                   
----                           -----                                                                                                                   
Count                          2                                                                                                                       
Name                           FooBar...whatever..2                                                                                                    
Age                            2                                                                                                                       
Type                           Human  

3 个答案:

答案 0 :(得分:4)

Hashtables是引用,当您创建一个对象时,所有进一步的操作都针对该哈希表,包括尝试检索该信息。

你可以在循环的每次运行中为一个新的哈希表进行declate来解决这个问题。

$allTests = New-Object System.Collections.ArrayList

1..10 | foreach {
    $singleTest = @{}
    $singleTest.add("Type", "Human")
    $singleTest.add("Count", $_)
    $singleTest.add("Name", "FooBar...whatever..$_")
    $singleTest.add("Age", $_)
    $allTests.Add($singleTest) | Out-Null
}

甚至可以减少一些臃肿。

$allTests = New-Object System.Collections.ArrayList
1..10 | foreach {
    $allTests.Add(@{
        Type = "Human"
        Count = $_
        Name = "FooBar...Whatever..$_"
        Age = $_
    }) | Out-Null
}

这两个答案都会给你预期的输出。

答案 1 :(得分:1)

@ ConnorLSW的答案在功能上是正确的。

我为您提供另一种解决方案,为您提供更大的灵活性。我发现自己构建了共享某些字段的自定义对象,所以不是在每次运行循环时创建新对象,而是可以像现在一样在循环外定义基础对象,然后在循环内部,您可以更改该实例的属性值,然后将它添加到您的收藏中:

$allTests.Add($singleTest.Psobject.Copy())

在插入之前,将内容复制到新对象。现在,您没有引用与在循环的下一次迭代期间更改的相同对象。

答案 2 :(得分:0)

由于散列表是通过引用传递的,因此您只需将多个对同一散列表的引用添加到arraylist中。您需要创建哈希表的新副本,然后将其添加到数组列表中。

当您想要将副本保存到arraylist时,一种选择是使用哈希表.clone()方法。

$allTests.Add($singleTest.clone()) | out-null