2016-12-04 5 views
0

最近PowerShellでスクリプトを開始しましたが、2D配列を複数の列でソートするのは難しいです。2D配列を1行で並べ替える

次のコードは正常に動作しています。私は2次元配列(5x4)を持っていて、2つの列で並べ替えます。最初に、2番目の列で、次に1番目の列で表示されます。

$table1 = ("hhctrl.ocx",21,503,"Microsoft® HTML Help Control"),("mscomct2.ocx",10,629,"Microsoft Common Controls 2 ActiveX Control DLL"),("msscript.ocx",2,86,"Microsoft ® Script Control"),("sysmon.ocx",15,384,"System Monitor Control"),("tdc.ocx",1,61,"TDC ActiveX Control") 
$table1_sorted = $table1 | Sort-Object @{Expression={$_[1]}; Ascending=$false}, @{Expression={$_[0]}; Ascending=$true} 

echo (var_dump $table1) 
echo (var_dump $table1_sorted) 

var_dumpはカスタム関数です。私は配列をデバッグするためにそれを作成しました。 Write-Hostおよびechoの場合、それらは配列を平坦化し、項目を区切りません(項目間のコンマはありません)。

hhctrl.ocx 21 503 Microsoft® HTML Help Control mscomct2.ocx 10 629 Microsoft Common Controls 2 ActiveX Control DLL msscript.ocx 2 86 Microsoft ® Script Control sysmon.ocx 15 384 System Monitor Control tdc.ocx 1 61 TDC ActiveX Control 

var_dump出力:

[ 
    [ 
     "hhctrl.ocx", 
     21, 
     503, 
     "Microsoft® HTML Help Control" 
    ], 
    [ 
     "mscomct2.ocx", 
     10, 
     629, 
     "Microsoft Common Controls 2 ActiveX Control DLL" 
    ], 
    [ 
     "msscript.ocx", 
     2, 
     86, 
     "Microsoft ® Script Control" 
    ], 
    [ 
     "sysmon.ocx", 
     15, 
     384, 
     "System Monitor Control" 
    ], 
    [ 
     "tdc.ocx", 
     1, 
     61, 
     "TDC ActiveX Control" 
    ] 
] 
[ 
    [ 
     "hhctrl.ocx", 
     21, 
     503, 
     "Microsoft® HTML Help Control" 
    ], 
    [ 
     "sysmon.ocx", 
     15, 
     384, 
     "System Monitor Control" 
    ], 
    [ 
     "mscomct2.ocx", 
     10, 
     629, 
     "Microsoft Common Controls 2 ActiveX Control DLL" 
    ], 
    [ 
     "msscript.ocx", 
     2, 
     86, 
     "Microsoft ® Script Control" 
    ], 
    [ 
     "tdc.ocx", 
     1, 
     61, 
     "TDC ActiveX Control" 
    ] 
] 

Iは一行と別の配列、 "テーブル" を使用する場合は、ソートはアレイを平ら。

$table2 = ,("hhctrl.ocx",21,503,"Microsoft® HTML Help Control") 
$table2_sorted = $table2 | Sort-Object @{Expression={$_[1]}; Ascending=$false}, @{Expression={$_[0]}; Ascending=$true} 

echo (var_dump $table2) 
echo (var_dump $table2_sorted) 

出力:一つだけの行があるとき

[ 
    [ 
     "hhctrl.ocx", 
     21, 
     503, 
     "Microsoft® HTML Help Control" 
    ] 
] 
[ 
    "hhctrl.ocx", 
    21, 
    503, 
    "Microsoft® HTML Help Control" 
] 

この問題が発生しました。何故ですか?

+0

:あなたは関係なく、常に結果(ゼロ、1または多数)の量の配列にパイプラインの結果をラップする場合は、配列の部分式演算子を使用する必要があります。 'Sort-Object -InputObject $ table2'を使用してもそれは起こりません –

+0

@ MathiasR.Jessenあなたの提案はうまくいかないようです。 '$ table2'(' $ table1'も)をそのまま返します。私は[Sort-Object | SS64.com](http://ss64.com/ps/sort-object.html)と[どのように-InputObjectが動作するのですか?](http://stackoverflow.com/a/35292369/2202732)を参照してください。 '-InputObject'を明示的に使用する例はありません。作業コードを提供できますか? – akinuri

+1

'$ table2_sorted = @($ table2 | Sort-Object ...)' – PetSerAl

答えて

0

Sort-Objectは配列を返しません。 returnパイプラインの個々の入力項目をソート順に書き込みます。あなたが見ることができるように

PS> 7,3,8,5,1 | Sort-Object | ForEach-Object { Write-Host "Item: $_" } 
Item: 1 
Item: 3 
Item: 5 
Item: 7 
Item: 8 

は、パイプラインForEach-Objectの次のコマンドは、全体として、個々のアイテムではなく、配列を参照してください。

$table1で配列に折り返すパイプラインの最後のコマンドがパイプライン内に複数の項目を書き込んだために発生することがあります。 $table2パイプラインの最後のコマンドでは1つの項目しか書いていないので、そこで必要なラッピングはありません。それはあなたの1項目の配列を平らパイプラインだ

$Results = @(First-Command | Middle-Command | Last-Command) 
+0

"パイプライン"に書き込まれた複数の項目は配列として扱われるので、 '$ table1_sorted'は配列の配列です。 '$ table2_sorted'は2Dではありません。なぜなら、' Sort-Object'は1つのアイテムしか返さず、1つのアイテムだけが配列として扱われないからです。並べ替え出力を '$ sorted = @($ table | Sort-Object ...)'配列にラップすると、項目数に関係なく、常に項目を含む配列が得られます。今は理にかなっている。 – akinuri