Browse Source

Merge branch 'qistoph-numsort'

n1474335 8 years ago
parent
commit
2dbe2d044e
3 changed files with 66 additions and 1 deletions
  1. 32 1
      src/core/operations/SeqUtils.js
  2. 1 0
      test/index.js
  3. 33 0
      test/tests/operations/SeqUtils.js

+ 32 - 1
src/core/operations/SeqUtils.js

@@ -26,7 +26,7 @@ const SeqUtils = {
      * @constant
      * @default
      */
-    SORT_ORDER: ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address"],
+    SORT_ORDER: ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric"],
 
     /**
      * Sort operation.
@@ -47,6 +47,8 @@ const SeqUtils = {
             sorted = sorted.sort(SeqUtils._caseInsensitiveSort);
         } else if (order === "IP address") {
             sorted = sorted.sort(SeqUtils._ipSort);
+        } else if (order === "Numeric") {
+            sorted = sorted.sort(SeqUtils._numericSort);
         }
 
         if (sortReverse) sorted.reverse();
@@ -221,6 +223,35 @@ const SeqUtils = {
         return a_ - b_;
     },
 
+
+    /**
+     * Comparison operation for sorting of numeric values.
+     *
+     * @author Chris van Marle
+     * @private
+     * @param {string} a
+     * @param {string} b
+     * @returns {number}
+     */
+    _numericSort: function _numericSort(a, b) {
+        let a_ = a.split(/([^\d]+)/),
+            b_ = b.split(/([^\d]+)/);
+
+        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])) {
+                let 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 0;
+    },
+
 };
 
 export default SeqUtils;

+ 1 - 0
test/index.js

@@ -20,6 +20,7 @@ import "./tests/operations/FlowControl.js";
 import "./tests/operations/Image.js";
 import "./tests/operations/MorseCode.js";
 import "./tests/operations/StrUtils.js";
+import "./tests/operations/SeqUtils.js";
 
 let allTestsPassing = true;
 const testStatusCounts = {

+ 33 - 0
test/tests/operations/SeqUtils.js

@@ -0,0 +1,33 @@
+/**
+ * SeqUtils tests.
+ *
+ * @author Chris van Marle
+ * @copyright Copyright 2017
+ * @license Apache-2.0
+ */
+import TestRegister from "../../TestRegister.js";
+
+TestRegister.addTests([
+    {
+        name: "SeqUtils - Numeric sort photos",
+        input: "Photo-1.jpg\nPhoto-4.jpg\nPhoto-2.jpg\nPhoto-3.jpg\n",
+        expectedOutput: "Photo-1.jpg\nPhoto-2.jpg\nPhoto-3.jpg\nPhoto-4.jpg\n",
+        recipeConfig: [
+            {
+                "op": "Sort",
+                "args": ["Line feed", false, "Numeric"]
+            }
+        ],
+    },
+    {
+        name: "SeqUtils - Numeric sort CVE IDs",
+        input: "CVE-2017-1234,CVE-2017-9999,CVE-2017-10000,CVE-2017-10001,CVE-2017-12345,CVE-2016-1234,CVE-2016-4321,CVE-2016-10000,CVE-2016-9999,CVE-2016-10001",
+        expectedOutput: "CVE-2017-12345,CVE-2017-10001,CVE-2017-10000,CVE-2017-9999,CVE-2017-1234,CVE-2016-10001,CVE-2016-10000,CVE-2016-9999,CVE-2016-4321,CVE-2016-1234",
+        recipeConfig: [
+            {
+                "op": "Sort",
+                "args": ["Comma", true, "Numeric"]
+            }
+        ],
+    },
+]);