PowerShell 数组取消移位

jsu*_*sjr 5 arrays powershell

在阅读Windows PowerShell 博客上这篇有用的文章后,我意识到我可以“移动”数组的第一部分,但不知道如何在 PowerShell 中“取消移动”或将元素推送到数组的前面。

我正在创建一个哈希对象数组,最后读取的项目首先推送到数组上。我想知道是否有更好的方法来实现这一点。

## Create a list of files for this collection, pushing item on top of all other items
if ($csvfiles[$collname]) {
    $csvfiles[$collname] = @{ repdate = $date; fileobj = $csv }, $csvfiles[$collname] | %{$_}
}
else {
    $csvfiles[$collname] = @{ repdate = $date; fileobj = $csv }
}
Run Code Online (Sandbox Code Playgroud)

有几点需要注意:

  1. 我需要使用 foreach 循环 %{$_} 展开前一个数组元素,因为仅引用该数组就会创建一个嵌套数组结构。我必须让所有元素处于同一水平。
  2. 我需要区分空数组和包含元素的数组。如果我尝试展开一个空数组,它会在数组末尾放置一个 $null 元素。

想法?

PS:空哈希元素产生 NULL 值的原因是 $null 在 PowerShell 中被视为标量。有关详细信息,请参阅https://connect.microsoft.com/PowerShell/feedback/details/281908/foreach-should-not-execute-the-loop-body-for-a-scalar-value-of-null

回答:

看起来最好的解决方案是在必要时预先创建空数组,而不是围绕 $null 问题编写代码。下面是使用 .NET ArrayList 和本机 PoSh 数组进行的重写。

if (!$csvfiles.ContainsKey($collname)) {
    $csvfiles[$collname] = [System.Collections.ArrayList]@()
}
$csvfiles[$collname].insert(0, @{ repdate = $repdate; fileobj = $csv })

## NATIVE POSH SOLUTION...
if (!$csvfiles.ContainsKey($collname)) {
    $csvfiles[$collname] = @()
}
$csvfiles[$collname] = @{ repdate = $repdate; fileobj = $csv }, `
                       $csvfiles[$collname] | %{$_}
Run Code Online (Sandbox Code Playgroud)

Sas*_*sha 5

您可以简单地使用加号运算符:

$array = @('bar', 'baz')
$array = @('foo') + $array
Run Code Online (Sandbox Code Playgroud)

注意:这重新创建实际上创建了一个新数组,而不是更改现有数组(但$head, $tail = $array您提到的移动方式的工作方式完全相同)。


zda*_*dan 4

您可能想改用ArrayList对象,因为它们支持在任意位置插入。例如:

# C:\> $a = [System.Collections.ArrayList]@(1,2,3,4)
# C:\> $a.insert(0,6)
# C:\> $a
6
1
2
3
4
Run Code Online (Sandbox Code Playgroud)