I need to sort a list with multilevel indexes
(@('1', '2', '3', '1.1.1', '1.99', '2.5', '5.5', "10") | Sort-Object) -join ", "
1, 1.1.1, 1.99, 10, 2, 2.5, 3, 5.5
I came up with such a solution, but it does not work with indexes above ten
(@('1', '2', '3', '1.1.1', '1.99', '2.5', '5.5', "10") | Sort-Object {
$chanks = $_.Split('.')
$sum = 0
for ($i = 0; $i -lt $chanks.Count; $i++) {
$sum += [int]$chanks[$i] / [math]::Pow(10, $i)
}
$sum
}) -join ", "
1, 1.1.1, 2, 2.5, 3, 5.5, 10, 1.99
Here's a couple of solutions with some caveats.
The
-Propertyparameter ofSort-Objectaccepts an array, so you can specify "sort by...then by...". If you know the maximum number of "sub-indices" is 2 (i.e.x.y.z) then you can break the string apart into components separated by.and then sort successively by each component as an integer. It's repetitive, but it works...If a component is not specified (e.g.
'1.2'.Split('.')[2]) then, helpfully, it becomes0when casting to an[Int32].Here's an alternative that only uses one
[ScriptBlock]but it also requires that the maximum length of a sub-index in digits is known, too...That is padding each input index to have the same number of sub-indices and each sub-index to have the same number of digits and then relying on lexical sorting to put them in the correct order, so this...
...gets sorted as if it looked like this...
I suppose you could set both
$maxComponentCountand$maxComponentDigitsto, say,100if neither value is known, but that feels like a clunky workaround (with performance implications, too). I'll try to think of something better.