7

私は次のことを行うPowerShellスクリプトを持っています

$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の結果の配列に対して「INNERJOIN 」を実行しています。ForEach-Object$somePSObjectHashtablesを使用して簡単に反復処理し、配列の各メンバーでHashtable.Clone()を呼び出すことができます。次に、PSObjectのディープコピーを取得するために使用できます。New-Object PSObject -Property $someHashTable[$i]

私の質問は、中間のハッシュテーブルなしで、ディープコピーを作成する簡単な方法はありますか?

4

3 に答える 3

9

これはもっと短く、おそらく少しきれいなバージョンであることに注意してください(私はとても楽しんでいます):

$data = Import-Csv .\test.csv

$serialData = [System.Management.Automation.PSSerializer]::Serialize($data)

$data2 = [System.Management.Automation.PSSerializer]::Deserialize($serialData)

注:ただし、奇妙なことに、順序付けされたハッシュテーブルの順序は保持されません。

$data = [ordered] @{
    1 = 1
    2 = 2
}

$serialData = [System.Management.Automation.PSSerializer]::Serialize($data)

$data2 = [System.Management.Automation.PSSerializer]::Deserialize($serialData)
$data2

出力します:

Name                           Value
----                           -----
2                              2
1                              1

他のタイプでは問題なく動作します。

$data = [PsCustomObject] @{
    1 = 1
    2 = 2
}

$data = @(1, 2, 3)
于 2019-06-28T07:36:54.357 に答える
6

非常に深いコピーを取得するために、バイナリシリアル化を使用できます(すべてのデータがシリアル化可能であると想定しています。これは、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
于 2012-02-09T07:27:34.410 に答える
3

これが私が関数として使用するさらに短いものです:

using namespace System.Management.Automation
function Clone-Object ($InputObject) {
    <#
    .SYNOPSIS
    Use the serializer to create an independent copy of an object, useful when using an object as a template
    #>
    [psserializer]::Deserialize(
        [psserializer]::Serialize(
            $InputObject
        )
    )
}
于 2020-06-24T15:55:19.863 に答える