I have an array of strings that represent age ranges:
$AgeRanges = (
"<1",
"1-4",
"5-9",
"10-14",
"15-19",
"20-24",
"25-29",
"30-34",
"35-39",
"40-44",
"45-49",
"50+"
)
And if I sort them with Sort-Object I will get:
$AgeRanges | Sort-Object
<1
10-14
1-4
15-19
20-24
25-29
30-34
35-39
40-44
45-49
50+
5-9
After trying to split the strings and then convert them to integers and sort them that way and then reconstituting them with the string characters and converting them back to strings, I gave up and just hard coded the list into my script. But I have other such list that deal with children and babies.
Is there any elegant way to handle this type of problem that I am missing? Prompt the user to supply the age ranges? Shuffle the array around in fixed manner?
You can pass a calculated property expression to Sort-Object
and have it sort based on some derived value - like the first set of digits!
$AgeRanges |Sort-Object {$_-notlike'<*'},{($_-replace '^.*?(\d+).*$','$1') -as [int]}
The first expression will sort the input into 2 groups - those starting with <
go before the rest - this ensures the lower open range (<1
) always goes first.
The regex pattern ^.*?(\d+).*$
will match the entire string, capturing the first consecutive sequence of digits ((\d+)
), and then replacing the whole thing with just that - ie. <1
becomes 1
, 15-19
becomes 15
, etc.
The conversion to [int]
will force Sort-Object
to sort by ordinal numeric value rather than alphabetical, so you get 5-9
before 45-49
and so on.