深度复制一个数组

3

我在这个问题上苦思冥想。
我知道如果我在Powershell中创建一个数组,然后复制这个数组,它会被复制为引用类型而不是值类型。
所以,经典的例子是:

$c = (0,0,0)
$d = $c
$c[0] = 1
$d
1
0
0

解决办法是执行$d = $c.clone() 但是,如果数组本身是引用类型的集合,则此方法不起作用。这就是我的问题所在。我试图创建一个进程数组来跟踪 CPU 使用情况,通过创建 Process 数组,等待一段时间,然后检查最新值并计算差异来完成。但是 Get-Process 创建了一个引用数组。因此,当我执行以下操作时:
$a = ps | sort -desc id | where-object {$_.CPU -gt 20} #Get current values
$b = $a.clone() #Create a copy of those values.
sleep 20 #Wait a few seconds for general CPU usage...

$a = ps | sort -desc id | where-object {$_.CPU -gt 20} #Get latest values.
$a[0]  
$b[0] #returns the same value as A.

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessNam
-------  ------    -----      ----- -----   ------     -- ----------
   3195      57    90336     100136   600    83.71   7244 OUTLOOK

$a$b始终返回相同的值。如果我尝试使用类似于$b [0] =“$a [0] .clone()”逐个输入,PS会抱怨无法在此情况下使用Clone。

有什么建议吗?

另外,只是为了提醒一下,第二个$a = PS | ....行实际上并不需要,因为$a是对PS列表对象的引用类型,每当调用$a时,它都会更新并返回最新的值。我包含它只是为了让我在这里要达到的目标更清晰。


你也可以使用序列化 - jpaugh
2个回答

5
要复制一个数组,你可以执行以下操作:
$c = (0,0,0)
$d = $c | foreach { $_ }
$c[0] = 1
"c is [$c]"
"d is [$d]"

结果

c is [1 0 0]
d is [0 0 0]

针对您的问题(比较进程的CPU使用率),正如Keith所指出的那样,更具体的内容可能会更好。


2
当数组的元素是对象引用时,这种方法不起作用。$d=$c|%{$_}仍然将对象的引用复制到$d中,因此当您更改$c[0]中的元素属性时,您会在$d中看到该更改。 - Cary

1
从技术上讲,$d = $c 并不是任何类型的数组复制(引用或值)。它只是将指向 $c 所引用的数组的引用存储到 $d 中。我认为你只需要一次获取进程数组,然后调用 Refresh 方法。在此之前,你需要先检查 Exited 属性以确保相关进程仍在运行。当然,如果你对启动的新进程感兴趣,这种方法就无法帮助你了。在这种情况下,你需要在不同时间获取进程快照,筛选出两个数组之间的交集(根据进程 ID),然后计算它们属性值的差异 - 再次基于进程 ID。为了使这更容易,你可能需要将每个快照放入一个哈希表中,并以进程 ID 为键。

啊,当然。好主意。实际上,我只需要ID和CPUs的值。这样我就可以将它们转储到散列表中: foreach ($_ in $psCurrentList) { $psPreviousList.add($_.id,$_.cpu) }这样做很好,谢谢。 - EtanSivad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接