用一行对2D数组排序 [英] Sorting a 2D array with one row
问题描述
我最近开始在PowerShell中编写脚本,但在按多列对2D数组进行排序时遇到了困难.
I've recently started scripting in PowerShell and I'm having a difficulty in sorting a 2D array by multiple columns.
以下代码运行正常.我有一个2D数组(5x4),并按两列对其进行排序;首先,在第二列之前,然后在第一列之前.
The following code is working fine. I have a 2D array (5x4) and I sort it by two columns; first, by the second column, and then by the first column.
$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
,它们都使数组变平并且不分隔项目(项目之间没有逗号)
var_dump
is a custom function. I've created it to debug arrays. Write-Host
and echo
, they both flatten the arrays and don't seperate the items (no comma between items) e.g.
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"
]
]
现在,如果我使用只有一个行的另一个数组表",则将数组变平.
Now, if I use another array, "table" with only one row, sorting flattens the array.
$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"
]
只有一行时会发生这种情况.为什么会这样?
This happens when there's only one row. Why is that?
推荐答案
Sort-Object
不返回数组.它返回以排序顺序写入管道各个输入项.
Sort-Object
does not return array. It return write to pipeline individual input items in sorted order.
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
中的下一个命令可以看到每个单独的项目,但不能看到整个数组.
As you can see, next command in pipeline ForEach-Object
see each individual item, but not array as whole.
在$table1
情况下包装到数组会发生,因为管道中的最后一个命令在管道中写入了多个项目.在$table2
情况下,管道中的最后一条命令仅写入了一项,因此在此不需要包装.如果要始终将流水线结果包装到数组中而不考虑结果量(零,一个或多个),则需要使用数组子表达式运算符:
Wrapping to array in $table1
case happens, because last command in pipeline wrote more than one item in pipeline. In $table2
case last command in pipeline wrote only one item, so no wrapping necessary there. If you want to always wrap pipeline results into array regardless of amount of results (zero, one or many), then you need to use array subexpression operator:
$Results = @( First-Command | Middle-Command | Last-Command )
这篇关于用一行对2D数组排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!