arrays - 使用数组作为值对哈希表进行排序

标签 arrays powershell sorting hashtable powershell-5.0

描述 :我正在构建一个 PowerShell 脚本来搜索文件,然后为它们提供唯一的名称,复制它们,然后通过哈希计算验证它们 - 我选择将脚本拆分为每个步骤的函数,因此更容易维护整个事情。
为了将所有值从一个函数获取到另一个函数,我选择使用 [hashtable]$FooBar - 在 $FooBar 内部,有多个数组,例如 FullNameOutputPath (每个文件可能会更改,因为它们将被复制到名为 yyyy-mm-dd 的子文件夹)。所有数组都相互关联(意味着索引 1 包含第一个文件的所有值,索引 2 包含第二个文件的值,...),到目前为止,这工作正常。

一个简短的简化可视化:

$FooBar = @{}
$FooBar.FullName = @()
$FooBar.Size = @()
$FooBar.Ext = @()
Get-ChildItem | ForEach-Object {
    $FooBar.FullName += $_.FullName
    $FooBar.Size += $_.Length
    $FooBar.Ext += $_.Extension
}

但是,我现在需要按其中一个数组的一个值集对它们进行排序,例如尺寸。或者,再次可视化:
# From:
$FooBar
Name                           Value
----                           -----
fullname                       {D:\AAA.XYZ, D:\BBB.ZYX, D:\CCC.YZX}
size                           {222, 111, 555}
extension                      {.XYZ, .ZYX, .YZX}

# To:
$FooBar = $FooBar | Sort-Object -Property Size -Descending
$FooBar
Name                           Value
----                           -----
fullname                       {D:\CCC.YZX, D:\AAA.XYZ, D:\BBB.ZYX}
size                           {555, 222, 111}
extension                      {.YZX, .XYZ, .ZYX}

我试过 $FooBar.GetEnumerator() | Sort-Object -Property Size ,但这不会改变任何东西。谷歌提出了关于如何对一系列哈希表进行排序的建议,但在我的情况下,它是相反的,我无法理解这一点,因为我什至不明白为什么这是一个问题摆在首位.

所以我的问题是 :有没有办法通过数组之一的值集对哈希表中的所有数组进行排序?我无法理解这一点。

免责声明:我是一个 PowerShell 自学者,在脚本/编程方面没有合理的背景,所以很可能我的“将所有内容都包含在一个哈希表中”-解决方案根本不起作用或可能效率极低 - 如果是这样, 请告诉我。

最佳答案

我相信你正在尝试做的最简单的方法是 Select-Object

$fooBar = Get-ChildItem | Select-Object FullName, Size, Extension

这将创建一组仅具有所需属性的新对象。这有效而您的方法无效的原因是因为 Sort-Object 适用于属性,而您指定的属性位于几层之后。

如果您需要更多的灵活性而不仅仅是精确的属性,您可以像这样创建自己的
$fooBar = Get-ChildItem | Select-Object @{Name = 'SizeMB'; Expression = {$_.Size / 1MB}}

或者使用 [PSCustomObject] 类型加速器手动创建新属性:
$fooBar = Get-ChildItem | ForEach-Object {
    [PSCustomObject]@{
        FullName = $_.FullName
        Extension = $_.Extension
        Size = $_.Size
    }
}

更新

如果您需要在最初创建对象后向该对象添加其他属性,您有几个选择。

添加成员

目前最常用的方法是使用 Add-Member cmdlet。
$object | Add-Member -MemberType NoteProperty -Name NewProperty -Value 'MyValue'

$object

需要记住的重要一点是,默认情况下,此 cmdlet 不返回任何内容。因此,如果您将上述语句放在函数的末尾并且不单独返回对象,则您的函数将不会返回任何内容。确保您使用 -PassThru 参数(这对于链接 Add-Member 命令也很有用)或之后调用变量(如上面的示例)

选择对象

使用计算属性添加成员时,您可以选择所有以前的属性。请记住,由于 Select-Object 的工作方式,源对象中的所有方法都不会被继承。
$fooBar | Select-Object *, @{Name = 'NewProperty'; Expression = {'MyValue'}}

psobject.Properties

这是我个人最喜欢的,但它仅限于 PowerShell 的更高版本,我实际上还没有看到其他人使用它。
$fooBar.psobject.Properties.Add([psnoteproperty]::new('NewProperty', 'MyValue'))
$fooBar

每个成员类型都有它自己的构造函数。您还可以向 $fooBar.psobject.Methods 添加方法或向 $fooBar.psobject.Members 添加任一类型。我喜欢这种方法,因为它感觉更明确,并且使用成员添加成员感觉正确。

概括

您选择的方法主要是偏好。如果可能,我会推荐 Add-Member 因为它是最常用的,因此具有更好的可读性和更多的人可以回答有关它的问题。

我还想提一下,如果可能的话,通常最好避免添加其他成员。理想情况下,函数的返回值应该具有可靠的形式。如果有人正在使用您的函数,并且他们必须猜测您的对象上何时会存在属性或方法,则调试将变得非常困难。显然,这不是一个硬性规定,但如果您需要添加成员,您至少应该考虑重构是否更好。

关于arrays - 使用数组作为值对哈希表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45000851/

相关文章:

python - 计算数据帧中每一行有多少个连续的 TRUE

powershell - Powershell脚本可交互工作,而不是在脚本内

powershell - 尝试将CS​​V和哈希表中的数据混合以创建变量

C 编程为什么我的代码不能使用嵌套结构数组打印正确的输出?

arrays - 仅替换字符串中的第一个字符 | swift

amazon-web-services - AWS CLI Update_Stack 无法传递包含/的参数值

python - 在 python 字典中排序键值对列表

java - 来自文本文件的数据评估

ios - 如何基于多个属性和非属性(方法)对NSMutableArray进行排序

php - 使用 php 找出匹配单词并从数组值中显示它的位置