2012-02-09 78 views
2

我有一个PowerShell脚本中,我做了以下深复制一个PSObject

$somePSObjectHashtables = New-Object Hashtable[] $somePSObject.Length; 
$somePSObjects = Import-CSV $csvPath 
0..($somePSObject.Length - 1) | ForEach-Object { 
    $i = $_; 
    $somePSObjectHashtables[$i] = @{}; 
    $somePSObject[$_].PSObject.Properties | ForEach-Object { 
     $somePSObjectHashtables[$i][$_.Name] = $_.Value; 
    } 
} 

我需要做的,因为我想在该CSV数据的几个不同的副本来执行几个不同的操作。从某种意义上说,我在PSObject的结果数组上执行“INNER JOIN”。我可以通过$somePSObjectHashtablesForEach-Object容易迭代并且阵列的每个成员上调用Hashtable.Clone()。然后我可以使用New-Object PSObject -Property $someHashTable[$i]来获得PSObject的深层副本。

我的问题是,是否有使深层副本的一些更简单的方法,而不需要中间的Hashtable?

+0

这可能是我怎么会已经结束了解决这样的问题。 – 2012-02-09 03:07:31

+0

只是为了确保条款。 'Hashtable.Clone()'做浅拷贝。我们是否在谈论深层复制? – 2012-02-09 06:55:53

+0

那么,在这个特殊的情况下,当数据来自CSV,将在事实上*深,因为性能或者是值类型(深拷贝,确实)或字符串(不深复制,但它们是不可变的,所以我们可能会考虑他们*深拷贝*在这个意义上)。 – 2012-02-09 07:03:16

回答

4

为了得到真正的深层副本,我们可以使用二进制序列(假设所有的数据都是可序列化,这绝对是来自CSV数据的情况下):

# Get original data 
$data = Import-Csv ... 

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

# Use deep copied data 
$data2 
+1

迟到接受的道歉。我[测试它](https://gist.github.com/2006846)它工作。有一件事我注意到ID必须明确地将Get-Date调用转换为DateTime,否则串行器会抱怨说无法序列化PSObject。 – 2012-03-09 14:56:13

+0

似乎无法序列化一个PSObject .. – 2013-11-22 13:41:06