2015-04-17 66 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()戰鬥之前絆倒這個解決方案:) –