PowerShell Sort-Object cmdlet更改顺序w.r.t.属性未排序

时间:2012-04-23 17:53:15

标签: sorting powershell

我正在对一些XML进行排序,并希望根据特定的非唯一属性对元素进行排序,这允许我对like-elements进行分组。在这些组中,我需要保持原始排序。问题是,在排序时,这些组内的顺序会发生变化,而当重新排序时,顺序会再次发生变化。如果XML的内容没有改变,我需要一种不会改变的东西(否则SVN差异是丑陋的)。这是一个简化的例子:

$xml = [xml]@"
<root>
  <element name="a" number="1" />
  <element name="b" number="1" />
  <element name="c" number="1" />
  <element name="d" number="2" />
  <element name="e" number="2" />
  <element name="f" number="2" />
  <element name="g" number="3" />
  <element name="h" number="3" />
</root>
"@

Write-Host "`nFirst Sort produces this:"
$result1 = $xml.SelectNodes('//element') | Sort-Object -Property 'number'
Write-Host (($result1 | select -ExpandProperty 'number') + " <---Sorted on")
Write-Host (($result1 | select -ExpandProperty 'name') + " <---Order not maintained")

Write-Host "`nSorting the (already sorted) results of First Sort produces this:"
$result2 = $result1 | Sort-Object -Property 'number'
Write-Host (($result2 | select -ExpandProperty 'number') + " <---Sorted on")
Write-Host (($result2 | select -ExpandProperty 'name') + " <---Order changed again")

这是输出:

First Sort produces this:
1 1 1 2 2 2 3 3  <---Sorted on
c b a f e d h g  <---Order not maintained

Sorting the (already sorted) results of First Sort produces this:
1 1 1 2 2 2 3 3  <---Sorted on
a b c d e f g h  <---Order changed again

在这个例子中,我需要保留“数字组”中的原始“名称”排序。

任何人都可以想到一种 easy 方式来保持原始顺序并在多次排序时出现相同的情况吗?

我正在尝试避免添加表示原始排序的虚拟属性。也许有一种不同的.NET排序功能更具确定性?我搜索过但似乎没有人关心在同等组内的排序。

感谢。

2 个答案:

答案 0 :(得分:1)

如果您没有已经代表自然排序顺序的东西,您可以使用Add-Member添加索引属性:

$nodes = @($xml.SelectNodes('//element'))
for ($i=0; $i -lt $nodes.Count; $i++) 
{
    $nodes[$i] = $nodes[$i] | Add-Member -MemberType NoteProperty "Index" $i -PassThru
}

$result1 = $nodes | Sort-Object name, Index

无论您重新排序多少次,都可以保证得到相同的顺序。

更新:为PowerShell v2添加了语法

答案 1 :(得分:0)

对两个属性进行排序:

$xml.SelectNodes('//element') | Sort-Object -Property number, name

这会产生此输出:

name     number
----     ------
a        1
b        1
c        1
d        2
e        2
f        2
g        3
h        3