I’m looking for an efficient way to sort a list of Alphanumeric labels but ignoring to sort the hexadecimal values like below.
arr = [
"a_19",
"a_2",
"b_645500",
"b_6d4500"
]
I’ve read the solution here
Using { numeric: true } will result in bad sort between hexadecimal values not the shown string label
arrNumeric = [
"a_2",
"a_19",
"b_6d4500",
"b_645500"
]
Removing numeric flag will cause bad sort between "a_19" and "a_2".
arrNonNumeric = [
"a_19",
"a_2",
"b_645500",
"b_6d4500"
]
the desired sorted array is:
arrSorted = [
"a_2",
"a_19",
"b_645500",
"b_6d4500"
]
please note that it’s possible to not use (_) in the labels to split each label based on this specific character to extract the non-numeric part
2
Answers
You will need to split on the
_
(underscore) and compare the left values first. If they are the same, check the right values. You need to determine the "type" of the value. I created a simple function calledvalueType
that determines if a given string is a decimal (dec
), hexadecimal (hex
), or a string (str
).Note that this is ad-hoc and you should denote hex values with
0x6d450
(prefixed with0x
).Create 2 compare functions with
Intl.Collator
and use them conditionally based on whether the both compared strings are numbers or not (test with a regexp).Note that in your particular case it’s not possible to distinguish a hex number consisting of 6 digits with an integer of 6 digits.
So that’s why here’s a regular expression
/Dd{1,5}$|Dd{7,}$/
which treats a 6 digit number as a hex value and compares it as a string. As the OP wanted the delimiter is any non-digit character.We also have problems with the number/hex delimiter. Assuming that’s not a digit (
D
) we need to check whether a potential number is not a hex (since for exampled
inside a hex could act as a number delimiter).Thus we should also do a negative check of a number against a hex string.
To test more accurately I’ve added
b_55
so it would be sorted against hex’s with theb_
prefix: