Repository: plexis-js/plexis (js)

Issue:
Feature: `compare / compareLikeHuman / naturalCompare`
For most cases, humans do not sort text as machines do.

```javascript
["A friend", 'Boo', "another one"].sort()
// => ["A friend", "Boo", "another one"] 😬
```

Let's fix that :)

```javascript
/**
 * @description Compares input text as humans do.
 * @param {String} first
 * @param {String} second
 * @returns {Integer}
 * @example
 * compare('', '') // => 0
 * compare('A', 'a') // => 1
 * compare('A', 'b') // => 1
 * compare('A woman', 'a woman') // => 1
 * compare('b', 'B') // => -1 
 * compare('C', 'b') // => -1 
 * compare('Qux20', 'Qux5') // => -1
 * compare('Qux10', 'Qux11') // => 1
 */
```


**Aliases**

```javascript
import compare from '@plexis/compare';
import {compare, compareLikeHuman, naturalCompare} from 'plexis';
```

Pull request:
feat: compare closes #87
Hi.

This is for #87 .

Brandon

Patch:
diff --git a/docs/pages/api.md b/docs/pages/api.md
index d8497a1..eae38d5 100644
--- a/docs/pages/api.md
+++ b/docs/pages/api.md
@@ -1,6 +1,7 @@
 ## API
 
 - [cache](/packages/cache)
+- [compare](/packages/compare)
 - [compose](/packages/compose)
 - [distance](/packages/distance)
 - [escapeHTML](/packages/escapeHTML)
diff --git a/packages/compare/README.md b/packages/compare/README.md
new file mode 100644
index 0000000..e3a0f84
--- /dev/null
+++ b/packages/compare/README.md
@@ -0,0 +1,22 @@
+## `compare`
+
+Compares input text as humans do.
+
+`npm i @plexis/compare`
+
+**Usage**
+
+```javascript
+import naturalCompare from '@plexis/compare';
+
+compare('A', 'b'); // returns 1
+compare('A woman', 'a woman'); // returns 1
+compare('b', 'B'); // returns -1
+```
+
+**Aliases**
+
+```javascript
+import compare from '@plexis/compare';
+import {compare, compareLikeHuman, naturalCompare} from 'plexis';
+```
diff --git a/packages/compare/package.json b/packages/compare/package.json
new file mode 100644
index 0000000..b062fe8
--- /dev/null
+++ b/packages/compare/package.json
@@ -0,0 +1,27 @@
+{
+  "name": "@plexis/compare",
+  "version": "0.0.21",
+  "main": "dist/index.js",
+  "module": "dist/index.esm.js",
+  "jsnext:main": "./src/index.js",
+  "files": [
+    "dist", 
+    "src"
+  ],
+  "author": "Brandon Skinner <brandon.m.skinner@gmail.com>",
+  "license": "MIT",
+  "keywords": [
+    "utility",
+    "string",
+    "parse",
+    "format",
+    "validate"
+  ],
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/plexis-js/plexis.git"
+  },
+  "publishConfig": {
+    "access": "public"
+  }
+}
\ No newline at end of file
diff --git a/packages/compare/src/index.js b/packages/compare/src/index.js
new file mode 100644
index 0000000..badecaa
--- /dev/null
+++ b/packages/compare/src/index.js
@@ -0,0 +1,24 @@
+/*
+ * @description Compares input text as humans do.
+ * @param {String} first
+ * @param {String} second
+ * @returns {Integer}
+ * @example
+ * compare('', '') // => 0
+ * compare('A', 'a') // => 1
+ * compare('A', 'b') // => 1
+ * compare('A woman', 'a woman') // => 1
+ * compare('b', 'B') // => -1
+ * compare('C', 'b') // => -1
+ * compare('Qux20', 'Qux5') // => -1
+ * compare('Qux10', 'Qux11') // => 1
+ */
+const compare = (first, second) => {
+  return second.localeCompare(first, undefined, {
+    numeric: true,
+    sensitivity: 'case',
+    caseFirst: 'upper'
+  });
+};
+
+export default compare;
diff --git a/packages/plexis/package.json b/packages/plexis/package.json
index e0887af..12d9689 100644
--- a/packages/plexis/package.json
+++ b/packages/plexis/package.json
@@ -13,6 +13,7 @@
   ],
   "license": "MIT",
   "dependencies": {
+    "@plexis/compare": "^0.0.21",
     "@plexis/compose": "^0.0.21",
     "@plexis/distance": "^0.0.21",
     "@plexis/escape-html": "^0.0.21",
diff --git a/packages/plexis/src/index.js b/packages/plexis/src/index.js
index 042f0e2..877d911 100644
--- a/packages/plexis/src/index.js
+++ b/packages/plexis/src/index.js
@@ -1,3 +1,8 @@
+export {
+  default as compare,
+  default as compareLikeHuman,
+  default as naturalCompare
+} from '@plexis/compare';
 export {default as compose, default as _do} from '@plexis/compose';
 export {
   default as calcLevenshtein,


Test patch:
diff --git a/packages/compare/test/index.js b/packages/compare/test/index.js
new file mode 100644
index 0000000..b4c9252
--- /dev/null
+++ b/packages/compare/test/index.js
@@ -0,0 +1,12 @@
+import compare from '../src';
+
+it('Should compare strings naturally', () => {
+  expect(compare('', '')).toBe(0);
+  expect(compare('A', 'a')).toBe(1);
+  expect(compare('A', 'b')).toBe(1);
+  expect(compare('A woman', 'a woman')).toBe(1);
+  expect(compare('b', 'B')).toBe(-1);
+  expect(compare('C', 'b')).toBe(-1);
+  expect(compare('Qux20', 'Qux5')).toBe(-1);
+  expect(compare('Qux10', 'Qux11')).toBe(1);
+});
diff --git a/packages/plexis/test/__snapshots__/index.js.snap b/packages/plexis/test/__snapshots__/index.js.snap
index 6239750..b32e9e2 100644
--- a/packages/plexis/test/__snapshots__/index.js.snap
+++ b/packages/plexis/test/__snapshots__/index.js.snap
@@ -3,6 +3,9 @@
 exports[`allows using all the available utilities 1`] = `
 Array [
   "__esModule",
+  "compare",
+  "compareLikeHuman",
+  "naturalCompare",
   "compose",
   "_do",
   "calcLevenshtein",