@@ -38,7 +38,7 @@ class Sort extends Operation {
{
"name": "Order",
"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);
} else if (order === "Numeric") {
sorted = sorted.sort(Sort._numericSort);
+ } else if (order === "Numeric (hexadecimal)") {
+ sorted = sorted.sort(Sort._hexadecimalSort);
if (sortReverse) sorted.reverse();
@@ -131,6 +133,44 @@ class Sort extends Operation {
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) {
+ let a_ = a.split(/([^\da-f]+)/i),
+ b_ = b.split(/([^\da-f]+)/i);
+
+ a_ = a_.map(v => {
+ const t = parseInt(v, 16);
+ return isNaN(t) ? v : t;
+ });
+ b_ = b_.map(v => {
+ 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;
@@ -30,4 +30,15 @@ TestRegister.addTests([
],
},
+ {
+ name: "SeqUtils - Hexadecimal sort",
+ input: "06,08,0a,0d,0f,1,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,2,3,4,5,7,9,b,c,e",
+ expectedOutput: "1,2,3,4,5,06,7,08,9,0a,b,c,0d,e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f",
+ recipeConfig: [
+ "op": "Sort",
+ "args": ["Comma", false, "Numeric (hexadecimal)"]
+ ],
+ },
]);