PowerShell完全复制数组

时间:2015-04-17 12:18:46

标签: arrays powershell

我正在尝试创建现有数组的完整副本。每次我尝试这个似乎都不起作用。问题是我正在修改新复制数组中的Object名称,但它们也在原始数组中进行了更改。

下面的代码是高度简化的,因为还有更多的事情发生,然后只重命名对象名称,但它证明了我认为的重点。

一些示例代码:

Function Get-Fruits {
    Param (
        $Fruits = @('Banana', 'Apple', 'Pear')
    )
    foreach ($F in $Fruits) {
        [PSCustomObject]@{
            Type = $F
        }
    }
}

$FruitsOriginal = Get-Fruits

Function Rename-ObjectName {
    # Copy the array here
    $FruitsNew = $FruitsOriginal # Not a true copy
    $FruitsNew = $FruitsOriginal | % {$_} # Not a true copy
    $FruitsNew = $FruitsOriginal.Clone() # Not a true copy

    $FruitsNew | Get-Member | ? MemberType -EQ NoteProperty | % {

        $Name = $_.Name

        $FruitsNew | % {
            $_ | Add-Member 'Tasty fruits' -NotePropertyValue $_.$Name
            $_.PSObject.Properties.Remove($Name)
        }
    }
}

Rename-ObjectName

所需的结果是2个完全独立的数组。

$ FruitsOriginal

Type
----
Banana
Apple
Pear

$ FruitsNew

Tasty fruits
------------
Banana
Apple
Pear

感谢您的帮助。

5 个答案:

答案 0 :(得分:9)

您可以使用序列化深度克隆阵列:

#Original data
$FruitsOriginal = Get-Fruits

# Serialize and Deserialize data using BinaryFormatter
$ms = New-Object System.IO.MemoryStream
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
$bf.Serialize($ms, $FruitsOriginal)
$ms.Position = 0

#Deep copied data
$FruitsNew = $bf.Deserialize($ms)
$ms.Close()

答案 1 :(得分:5)

# Copy the array here
$FruitsCopy = @()
$FruitsCopy = $FruitsCopy + $FruitsOriginal

答案 2 :(得分:3)

自Powershell 3.0以来,与Jaco's answer相同,但使用PSSerializer 它使用与CliXML兼容的Export-Clixml格式。 Import-Clixml我个人觉得更容易阅读 理论上,支持嵌套层次结构,最高可达[int32]::MaxValue级别深度

#   Original data
$FruitsOriginal     =    Get-Fruits
#   Serialize and Deserialize data using PSSerializer:
$_TempCliXMLString  =   [System.Management.Automation.PSSerializer]::Serialize($FruitsOriginal, [int32]::MaxValue)
$FruitsNew          =   [System.Management.Automation.PSSerializer]::Deserialize($_TempCliXMLString)
#   Deep copy done.

答案 3 :(得分:0)

根据您对对象的需求,以及它们是否足够简单(如您的示例所示),您只需用新对象替换它们。

$NewFruits = $FruitsOriginal | %{ [PSCustomObject]@{ "Tasty Fruits" = $_.Type } }

答案 4 :(得分:0)

如果您要复制包含所有“真实”值的对象/值数组,或者要快速过滤掉null和“ falsey”值,那么效果很好:

$FruitsNew = $FruitsOriginal|?{$_}