2015-04-17 22 views
4

我试图创建一个现有数组的完整副本。每次我尝试这个时,它似乎都不起作用。问题是,我正在修改新复制阵列中的对象名称,但它们在原始阵列中也发生了更改。PowerShell完全复制一个阵列

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

一些示例代码:

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 

谢谢您的帮助。

+1

嘿DarkLite ......是你有一个美味的新鲜_peer_最后一次是什么时候? – Matt

+0

在我的案例中,脚本专家和水果中的'字符串'使得演示代码更容易,哈哈。但如果我必须诚实,我更像香蕉粉丝。希望你当选,我投给你:) – DarkLite1

+0

你可能会让我与别人混淆,因为我不在奔跑(或者我?)。另外我试图指出,同伴拼写错误 – Matt

回答

8

您可以使用序列来深克隆你的数组:

#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() 
+0

非常棒!非常感谢哈科:) – DarkLite1

0

根据您需要的对象做什么,如果他们够简单(在你的例子),你可以只更换他们与一个新的对象。

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

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

由于Powershell的3.0,相同的方法Jaco's answer但使用PSSerializer
它使用与Export-Clixml & Import-Clixml兼容的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. 
+0

这是一个很棒的提示!感谢您加入 – DarkLite1

+0

不客气。不止一次,我在与$ _。psobject.Copy()战斗之前绊倒这个解决方案:) –