这是我的代码
$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
答案 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