2012-02-09 4 views
2

У меня есть Powershell скрипт, в котором я делаю следующееDeep Копирование 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 для выполнения нескольких различных манипуляций. В некотором смысле я выполняю «INNER JOIN» в результирующем массиве PSObject. Я могу легко выполнить итерацию через $somePSObjectHashtables с помощью ForEach-Object и вызвать Hashtable.Clone() на каждый элемент массива. Затем я смогу использовать New-Object PSObject -Property $someHashTable[$i], чтобы получить глубокую копию объекта PSObject.

Мой вопрос: есть ли более простой способ сделать глубокую копию без посредника Hashtable?

+0

Это, вероятно, как я бы в конечном итоге решение такой вопрос. –

+0

Просто, чтобы быть уверенным в терминах. 'Hashtable.Clone()' делает мелкие копии. Мы говорим о глубоких копиях или нет? –

+0

Ну, в этом конкретном случае, когда данные поступают из CSV, это будет * на самом деле * глубоким, потому что свойства - это либо типы значений (глубоко скопированные, действительно), либо строки (не глубокие скопированные, но они неизменяемы, поэтому мы можем рассмотреть они * глубоко скопированы * в этом смысле). –

ответ

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. –

+0

Невозможно сериализовать PSObject .. –

Смежные вопросы