【问题标题】:Using Sort-Object on array of hash tables在哈希表数组上使用 Sort-Object
【发布时间】:2016-05-04 17:13:10
【问题描述】:

在 PowerShell(版本 2)中创建以下哈希表数组后:

$array = @()
$array += @{a = 1; b = 5}
$array += @{a = 3; b = 4}
$array += @{a = 5; b = 9}
$array += @{a = 7; b = 2}

以下所有对 Sort-Object 的调用都返回相同的 {a,b} 序列:{5,9},{7,2},{1,5},{3,4}:

$array | Sort-Object
$array | Sort-Object -Descending
$array | Sort-Object a
$array | Sort-Object b
$array | Sort-Object "a"
$array | Sort-Object -Property a
$array.GetEnumerator() | Sort-Object
$array.GetEnumerator() | Sort-Object a

如果直接调用$array,它会按照输入的顺序返回对象,因此排序会改变顺序。但也许它没有比较器,所以只是将每个对象视为平等?

目标是对所有对象进行排序。我对涉及备用自定义对象、备用集合和/或备用排序例程的解决方法感到满意。

编辑:为了澄清我想要实现的目标,这将是 C# 中的粗略等价物

class MyClass {
    public int a;
    public int b;
}

// somewhere inside a method:
var objects = new List<MyClass>();
// code here to populate objects with some MyClass instances.
var sorted = objects.OrderBy(x => x.a);

【问题讨论】:

  • 按什么排序???如果您可以修改对象,那么为什么首先使用哈希表(难以排序)?
  • @FrodeF。显然按哈希表中的a 元素排序。
  • @EtanReisner 是的,这是正确的 - 使用哈希表中的元素作为排序键对哈希表进行排序。

标签: sorting powershell powershell-2.0


【解决方案1】:

Sort-Object a 不起作用,因为a 不是属性,它是哈希表中的键。有人可能会感到困惑,因为 PowerShell 通过接受 $ht.a 为您隐藏了这一点,即使它实际上在幕后使用了 $ht["a"],但如果您运行 $array | Get-Member,您可以确认属性 a 不存在。

一种解决方法是使用访问哈希表中的键的计算属性进行排序。我使用Select-Object 在表格中显示哈希表,以便更容易查看结果。例如:

$array = @()
$array += @{a = 7; b = 2}
$array += @{a = 3; b = 4}
$array += @{a = 3; b = 1}
$array += @{a = 5; b = 9}
$array += @{a = 1; b = 5}

#No sort
$array | Select-Object @{n="a";e={$_.a}}, @{n="b";e={$_.b}}

a b
- -
7 2
3 4
3 1
5 9
1 5

#Sort by a asc, then b asc
$array | Sort-Object { $_.a },  { $_.b } | Select-Object @{n="a";e={$_.a}}, @{n="b";e={$_.b}}

a b
- -
1 5
3 1
3 4
5 9
7 2

【讨论】:

  • 这可以解决问题 - 事实上$array | Sort-Object { $_.a}, { $_.b} 足以对对象进行排序,尽管 Select-Object 非常适合显示它们。
  • 正如我在“介绍”中所说,我只添加了Select-Object,因此很容易看到排序的结果。没有它,它将返回 a = 1, b =2, a = 2, b= 3 ...(每行一个键值对):-)
  • 哈哈,我只是放大了那里的代码 :-) 现在回去阅读顶部的解释,我感谢你 - 让我明白我的错误在哪里。跨度>
【解决方案2】:

有关详细说明,请参阅@Frode F. 的答案,但该答案确实错过了一种情况。当外部容器只有一项时(即数组只包含一个哈希表时),Sort-Object“方便地”对内部容器进行排序。

所以... 其中$array.Count -eq 1,该哈希表的元素已排序。 其中$array.Count -gt 1,对数组的元素进行排序。

作为一种解决方法,请使用:

if ($array.Count -gt 1) {
    $result = Sort-Object { $_.a }, {$_.b }
} else {
    $result = $array
}    

【讨论】:

    猜你喜欢
    • 2014-12-04
    • 2019-05-11
    • 2017-08-22
    • 2010-11-29
    • 2012-04-30
    • 2018-10-23
    • 2016-03-04
    • 2010-10-29
    相关资源
    最近更新 更多