【问题标题】:Sorting a 2D array with one row用一行对二维数组进行排序
【发布时间】:2017-04-18 16:30:00
【问题描述】:

我最近开始在 PowerShell 中编写脚本,但在按多列对二维数组进行排序时遇到了困难。

以下代码运行良好。我有一个二维数组(5x4),我按两列对其进行排序;首先是第二列,然后是第一列。

$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,它们都将数组展平并且不分隔项目(项目之间没有逗号),例如

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"
    ]
]

现在,如果我使用另一个数组,即只有一行的“表”,排序会使数组变平。

$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"
]

当只有一行时会发生这种情况。这是为什么呢?

【问题讨论】:

  • 这是使您的单项数组变平的管道。使用Sort-Object -InputObject $table2就不会发生
  • @MathiasR.Jessen 您的建议似乎不起作用。它只是返回不变的$table2(也是$table1)。我检查了Sort-Object | SS64.comHow does -InputObject work?。没有任何示例明确使用-InputObject。你能提供一个工作代码吗?
  • $table2_sorted = @( $table2 | Sort-Object ... )
  • @PetSerAl 奇怪的是,这行得通。如果我做对了,您将返回的值包装在一个数组中。我认为它还会将多行数组$table1 包装在另一个数组中,因此它会变成一个 3D 数组,但事实并非如此。它只是用一排 $table2 包装一个。我可以依靠这个吗?为什么不将$table1 包装在一个数组中?

标签: arrays sorting powershell multidimensional-array


【解决方案1】:

Sort-Object 不返回数组。它返回按排序顺序写入管道各个输入项。

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 情况下,管道中的最后一个命令只写了一项,因此不需要在那里进行包装。如果您想始终将管道结果包装到数组中而不考虑结果数量(零、一个或多个),那么您需要使用数组子表达式运算符:

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

【讨论】:

  • 因此,写入“管道”的多个项目被视为一个数组,因此$table1_sorted 是一个数组数组。 $table2_sorted 不是 2D 的,因为 Sort-Object “返回”只有一项,并且仅一项不被视为数组。如果我将排序输出包装在数组$sorted = @($table | Sort-Object ... ) 中,我总是会得到一个包含项目的数组,无论项目数是多少。现在说得通了。
猜你喜欢
  • 2018-06-02
  • 2013-08-17
  • 2015-09-17
  • 2017-05-25
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
相关资源
最近更新 更多