Support hexadecimal and other bases in numeric sorting

This commit is contained in:
Chris van Marle 2018-10-11 13:21:13 +02:00
parent d6c6981bc0
commit 0cbb17f7ce

View File

@ -38,7 +38,7 @@ class Sort extends Operation {
{ {
"name": "Order", "name": "Order",
"type": "option", "type": "option",
"value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric"] "value": ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric", "Numeric (hexadecimal)"]
} }
]; ];
} }
@ -62,6 +62,8 @@ class Sort extends Operation {
sorted = sorted.sort(Sort._ipSort); sorted = sorted.sort(Sort._ipSort);
} else if (order === "Numeric") { } else if (order === "Numeric") {
sorted = sorted.sort(Sort._numericSort); sorted = sorted.sort(Sort._numericSort);
} else if (order === "Numeric (hexadecimal)") {
sorted = sorted.sort(Sort._hexadecimalSort);
} }
if (sortReverse) sorted.reverse(); if (sortReverse) sorted.reverse();
@ -131,6 +133,48 @@ class Sort extends Operation {
return a.localeCompare(b); return a.localeCompare(b);
} }
/**
* Comparison operation for sorting of hexadecimal values.
*
* @author Chris van Marle
* @private
* @param {string} a
* @param {string} b
* @returns {number}
*/
static _hexadecimalSort(a, b) {
const a_ = a.split(/([^\da-f]+)/i),
b_ = b.split(/([^\da-f]+)/i);
for (let i = 0; i < a_.length; ++i) {
let t = parseInt(a_[i], 16);
if (!isNaN(t)) {
a_[i] = t;
}
}
for (let i = 0; i < b_.length; ++i) {
let t = parseInt(b_[i], 16);
if (!isNaN(t)) {
b_[i] = t;
}
}
for (let i = 0; i < a_.length && i < b.length; ++i) {
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
if (isNaN(a_[i]) && isNaN(b_[i])) {
const ret = a_[i].localeCompare(b_[i]); // Compare strings
if (ret !== 0) return ret;
}
if (!isNaN(a_[i]) && !isNaN(a_[i])) { // Compare numbers
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
}
}
return a.localeCompare(b);
}
} }
export default Sort; export default Sort;