用一行对2D数组排序 [英] Sorting a 2D array with one row

查看:63
本文介绍了用一行对2D数组排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始在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-Hostecho,它们都使数组变平并且不分隔项目(项目之间没有逗号)

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆