4

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 }
}

注意すべき点がいくつかあります。

  1. 配列を参照するだけでネストされた配列構造が作成されるため、foreachループ%{$_}を使用して前の配列要素を展開する必要があります。すべての要素を同じレベルにする必要があります。
  2. 空の配列と要素を含む配列を区別する必要があります。空の配列を展開しようとすると、配列の最後に$null要素が配置されます。

考え?

PS:空のハッシュ要素がNULL値を生成する理由は、PowerShellでは$nullがスカラーとして扱われるためです。詳細については、https://connect.microsoft.com/PowerShell/feedback/details/281908/foreach-should-not-execute-the-loop-body-for-a-scalar-value-of-nullを参照してください。

答え:

最善の解決策は、$ nullの問題を回避するコードではなく、必要に応じて空の配列を事前に作成することです。これは、.NETArrayListとネイティブ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] | %{$_}
4

2 に答える 2

4

代わりにArrayListオブジェクトを使用することをお勧めします。これらのオブジェクトは、任意の場所への挿入をサポートしているためです。例えば:

# C:\> $a = [System.Collections.ArrayList]@(1,2,3,4)
# C:\> $a.insert(0,6)
# C:\> $a
6
1
2
3
4
于 2012-11-21T23:46:17.577 に答える
3

プラス演算子を使用するだけです。

$array = @('bar', 'baz')
$array = @('foo') + $array

注:この再作成では、既存の配列を変更するのではなく、実際に新しい配列が作成されます(ただし、$head, $tail = $array参照するシフトの方法はまったく同じように機能します)。

于 2020-02-25T08:58:30.347 に答える