├── .babelrc ├── .eslintrc.json ├── .gitignore ├── LICENSE ├── README.md ├── dist └── main.js ├── package.json ├── src └── main.js └── test ├── sorter-tests.js └── words.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMap": true, 3 | "presets": [ 4 | "es2015" 5 | ], 6 | "plugins": [] 7 | } 8 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 6, 4 | "sourceType": "module", 5 | "ecmaFeatures": {} 6 | }, 7 | "extends": "eslint:recommended", 8 | "rules": { 9 | "quotes": [1, "single", "avoid-escape"], 10 | "semi": 2, 11 | "no-console": 0 12 | }, 13 | "plugins": [], 14 | "env": { 15 | "node": true, 16 | "es6": true 17 | }, 18 | "globals": { 19 | "before": false, 20 | "describe": false, 21 | "it": false 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | /docs 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # simple-sort 2 | 3 | `simple-sort` provides a straightforward collection of sorting methods and sort functions. 4 | 5 | ## Why use `simple-sort`? 6 | * It provides both sorting methods and sort functions. 7 | * It makes sorting by locale simple (no separate API to remember). 8 | * It provides functionality via plain English method names rather than hard-to-remember parameters. 9 | * It provides you a consistent sorting API, so you don't have to individually write all sorting methods yourself. 10 | * It makes your code more readable and easily understandable, even by somebody unfamiliar with the `simple-sort` API. 11 | 12 | ## Installation 13 | ``` 14 | $ npm install simple-sort 15 | ``` 16 | 17 | ## Usage 18 | Import the library: 19 | ```js 20 | import Sorter from 'simple-sort'; // or var Sorter = require('simple-sort').default; 21 | ``` 22 | Create an instance: 23 | ```js 24 | const sorter = new Sorter('en'); 25 | ``` 26 | ####Sorting methods: 27 | ```js 28 | // sample data array 29 | const numArr = [2,3,1]; 30 | 31 | // sort values in ascending order 32 | sorter.sortAsc(numArr); 33 | // -> [1,2,3] 34 | 35 | // sort values in descending order 36 | sorter.sortDes(numArr); 37 | // -> [3,2,1] 38 | 39 | // sample array 40 | const wordArr = ['Janeway', 'Picard', 'Cisco']; 41 | 42 | // sort by locale in ascending order 43 | sorter.sortByLocaleAsc(wordArr); 44 | // -> ['Cisco','Janeway','Picard'] 45 | 46 | // sort by locale in descending order 47 | sorter.sortByLocaleDes(wordArr); 48 | // -> ['Picard','Janeway','Cisco'] 49 | 50 | // sample array 51 | const objArr = [{num:2},{num:3},{num:1}]; 52 | 53 | // sort array of objects by property in ascending order 54 | sorter.sortByPropAsc(objArr, 'num'); 55 | // -> [{num:1},{num:2},{num:3}] 56 | 57 | // sort array of objects by property in descending order 58 | sorter.sortByPropDes(objArr, 'num'); 59 | // -> [{num:3},{num:2},{num:1}] 60 | 61 | // sample array 62 | const objStrArr = [{name:'Janeway'},{name:'Picard'},{name:'Cisco'}]; 63 | 64 | // locale sort array of objects by property in ascending order 65 | sorter.localeSortByPropAsc(objStrArr, 'name'); 66 | // -> [{name:'Cisco'},{name:'Janway'},{name:'Picard'}] 67 | 68 | // locale sort array of objects by property in descending order 69 | sorter.localSortByPropDes(objStrArr, 'name'); 70 | // -> [{name:'Picard'},{name:'Janway'},{name:'Cisco'}] 71 | 72 | ``` 73 | ####Function-returning methods: 74 | Each of the previous sort methods are also available as sort functions to pass into `Array.sort()`. All function-returning methods have a `Func` suffix. 75 | ```js 76 | // sample data array 77 | const numArr = [2,3,1]; 78 | 79 | // sort values in asending order 80 | numArr.sort(sorter.sortAscFunc()); 81 | // numArr -> [1,2,3] 82 | 83 | // sort values in descending order 84 | numArr.sort(sorter.sortDesFunc()); 85 | // numArr -> [3,2,1] 86 | 87 | // sample array 88 | const wordArr = ['Janeway', 'Picard', 'Cisco']; 89 | 90 | // sort by locale in ascending order 91 | wordArr.sort(sorter.sortByLocaleAscFunc()); 92 | // wordArr -> ['Cisco','Janeway','Picard'] 93 | 94 | // sort by locale in descending order 95 | wordArr.sort(sorter.sortByLocaleDesFunc()); 96 | // wordArr -> ['Picard','Janeway','Cisco'] 97 | 98 | // sample array 99 | const objArr = [{num:2},{num:3},{num:1}]; 100 | 101 | // sort array of objects by property in ascending order 102 | objArr.sort(sorter.sortByPropAscFunc('num')); 103 | // objArr -> [{num:1},{num:2},{num:3}] 104 | 105 | // sort array of objects by property in descending order 106 | objArr.sort(sorter.sortByPropDesFunc('num')); 107 | // objArr -> [{num:3},{num:2},{num:1}] 108 | 109 | // sample array 110 | const objStrArr = [{name:'Janeway'},{name:'Picard'},{name:'Cisco'}]; 111 | 112 | // locale sort array of objects by property in ascending order 113 | objStrArr.sort(sorter.localeSortByPropAscFunc('name')); 114 | // objStrArr -> [{name:'Cisco'},{name:'Janway'},{name:'Picard'}] 115 | 116 | // locale sort array of objects by property in descending order 117 | objStrArr.sort(sorter.localSortByPropDesFunc('name')); 118 | // objStrArr -> [{name:'Picard'},{name:'Janway'},{name:'Cisco'}] 119 | ``` 120 | 121 | ## Docs 122 | Documentation of all available methods can be found [here](https://github.com/rBurgett/simple-sort/wiki#sorter). 123 | 124 | ## Contributions 125 | Contributions are welcome! If you have any issues and/or contributions you would like to make, feel free to file an issue and/or issue a pull request. 126 | 127 | ## License 128 | Apache License Version 2.0 129 | 130 | Copyright (c) 2016 by Ryan Burgett. 131 | -------------------------------------------------------------------------------- /dist/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | var CollatorPolyfill = function CollatorPolyfill(locale) { 7 | this._locale = locale; 8 | }; 9 | CollatorPolyfill.prototype.compare = function (a, b) { 10 | return a.localeCompare(b, this._locale); 11 | }; 12 | 13 | /** 14 | * Constructs a sorter instance. 15 | * @constructor Sorter 16 | * @param {string} [locale] - the locale to sort by (e.g. 'en-US') 17 | */ 18 | var Sorter = function Sorter(locale) { 19 | this.intCol = Intl && Intl.Collator ? new Intl.Collator(locale) : new CollatorPolyfill(locale); 20 | }; 21 | 22 | Sorter.prototype._sort = function (arr, d) { 23 | return arr.concat().sort(function (a, b) { 24 | return a === b ? 0 : a > b ? d * 1 : d * -1; 25 | }); 26 | }; 27 | 28 | /** 29 | * Sorts values in ascending order. 30 | * @param {Array} arr - Array of value to sort 31 | * @returns {Array} a new sorted Array 32 | */ 33 | Sorter.prototype.sortAsc = function (arr) { 34 | return this._sort(arr, 1); 35 | }; 36 | 37 | /** 38 | * Sorts values in descending order. 39 | * @param {Array} arr - Array of value to sort 40 | * @returns {Array} a new sorted Array 41 | */ 42 | Sorter.prototype.sortDes = function (arr) { 43 | return this._sort(arr, -1); 44 | }; 45 | 46 | Sorter.prototype._sortFunc = function (d) { 47 | return function (a, b) { 48 | return a === b ? 0 : a > b ? d * 1 : d * -1; 49 | }; 50 | }; 51 | 52 | /** 53 | * Constructs a function to sort values in ascending order. 54 | * @returns {Function} 55 | */ 56 | Sorter.prototype.sortAscFunc = function () { 57 | return this._sortFunc(1); 58 | }; 59 | 60 | /** 61 | * Constructs a function to sort values in descending order. 62 | * @returns {Function} 63 | */ 64 | Sorter.prototype.sortDesFunc = function () { 65 | return this._sortFunc(-1); 66 | }; 67 | 68 | Sorter.prototype._sortByProp = function (arr, prop, d) { 69 | return arr.concat().sort(function (a, b) { 70 | return a[prop] === b[prop] ? 0 : a[prop] > b[prop] ? d * 1 : d * -1; 71 | }); 72 | }; 73 | 74 | /** 75 | * Sorts an Array of objects into ascending order by a certain property. 76 | * @param {Array} arr - Array of objects to sort 77 | * @param {string} prop - property to sort by 78 | * @returns {Array} a new sorted Array 79 | */ 80 | Sorter.prototype.sortByPropAsc = function (arr, prop) { 81 | return this._sortByProp(arr, prop, 1); 82 | }; 83 | 84 | /** 85 | * Sorts an Array of objects into descending order by a certain property. 86 | * @param {Array} arr - Array of objects to sort 87 | * @param {string} prop - property to sort by 88 | * @returns {Array} a new sorted Array 89 | */ 90 | Sorter.prototype.sortByPropDes = function (arr, prop) { 91 | return this._sortByProp(arr, prop, -1); 92 | }; 93 | 94 | Sorter.prototype._sortByPropFunc = function (prop, d) { 95 | return function (a, b) { 96 | return a[prop] === b[prop] ? 0 : a[prop] > b[prop] ? d * 1 : d * -1; 97 | }; 98 | }; 99 | 100 | /** 101 | * Constructs a function to sort values in ascending order by a certain property. 102 | * @param {string} prop - property to sort by 103 | * @returns {Function} 104 | */ 105 | Sorter.prototype.sortByPropAscFunc = function (prop) { 106 | return this._sortByPropFunc(prop, 1); 107 | }; 108 | 109 | /** 110 | * Constructs a function to sort values in descending order by a certain property. 111 | * @param {string} prop - property to sort by 112 | * @returns {Function} 113 | */ 114 | Sorter.prototype.sortByPropDesFunc = function (prop) { 115 | return this._sortByPropFunc(prop, -1); 116 | }; 117 | 118 | Sorter.prototype._localeSort = function (arr, d) { 119 | var _this = this; 120 | 121 | return arr.concat().sort(function (a, b) { 122 | return d * _this.intCol.compare(a, b); 123 | }); 124 | }; 125 | 126 | /** 127 | * Sorts values by locale in ascending order. 128 | * @param {Array} arr - Array of value to sort 129 | * @returns {Array} a new sorted Array 130 | */ 131 | Sorter.prototype.localeSortAsc = function (arr) { 132 | return this._localeSort(arr, 1); 133 | }; 134 | 135 | /** 136 | * Sorts values by locale in descending order. 137 | * @param {Array} arr - Array of value to sort 138 | * @returns {Array} a new sorted Array 139 | */ 140 | Sorter.prototype.localeSortDes = function (arr) { 141 | return this._localeSort(arr, -1); 142 | }; 143 | 144 | Sorter.prototype._localeSortFunc = function (d) { 145 | var _this2 = this; 146 | 147 | return function (a, b) { 148 | return d * _this2.intCol.compare(a, b); 149 | }; 150 | }; 151 | 152 | /** 153 | * Constructs a function to sort values by locale in ascending order. 154 | * @returns {Function} 155 | */ 156 | Sorter.prototype.localeSortAscFunc = function () { 157 | return this._localeSortFunc(1); 158 | }; 159 | 160 | /** 161 | * Constructs a function to sort values by locale in descending order. 162 | * @returns {Function} 163 | */ 164 | Sorter.prototype.localeSortDesFunc = function () { 165 | return this._localeSortFunc(-1); 166 | }; 167 | 168 | Sorter.prototype._localeSortByProp = function (arr, prop, d) { 169 | var _this3 = this; 170 | 171 | return arr.concat().sort(function (a, b) { 172 | return d * _this3.intCol.compare(a[prop], b[prop]); 173 | }); 174 | }; 175 | 176 | /** 177 | * Sorts an Array of objects by locale into ascending order by a certain property. 178 | * @param {Array} arr - Array of objects to sort 179 | * @param {string} prop - property to sort by 180 | * @returns {Array} a new sorted Array 181 | */ 182 | Sorter.prototype.localeSortByPropAsc = function (arr, prop) { 183 | return this._localeSortByProp(arr, prop, 1); 184 | }; 185 | 186 | /** 187 | * Sorts an Array of objects by locale into descending order by a certain property. 188 | * @param {Array} arr - Array of objects to sort 189 | * @param {string} prop - property to sort by 190 | * @returns {Array} a new sorted Array 191 | */ 192 | Sorter.prototype.localeSortByPropDes = function (arr, prop) { 193 | return this._localeSortByProp(arr, prop, -1); 194 | }; 195 | 196 | Sorter.prototype._localeSortByPropFunc = function (prop, d) { 197 | var _this4 = this; 198 | 199 | return function (a, b) { 200 | return d * _this4.intCol.compare(a[prop], b[prop]); 201 | }; 202 | }; 203 | 204 | /** 205 | * Constructs a function to sort values by locale in ascending order by a certain property. 206 | * @param {string} prop - property to sort by 207 | * @returns {Function} 208 | */ 209 | Sorter.prototype.localeSortByPropAscFunc = function (prop) { 210 | return this._localeSortByPropFunc(prop, 1); 211 | }; 212 | 213 | /** 214 | * Constructs a function to sort values by locale in descending order by a certain property. 215 | * @param {string} prop - property to sort by 216 | * @returns {Function} 217 | */ 218 | Sorter.prototype.localeSortByPropDesFunc = function (prop) { 219 | return this._localeSortByPropFunc(prop, -1); 220 | }; 221 | 222 | exports.default = Sorter; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-sort", 3 | "version": "0.1.2", 4 | "description": "Straightforward collection of sorting methods and sort functions.", 5 | "main": "./dist/main.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "build": "babel src --out-dir dist", 11 | "watch": "babel src --watch --out-dir dist", 12 | "test": "mocha --compilers js:babel-register", 13 | "generate-docs": "jsdoc src -r -d docs", 14 | "generate-markdown-docs": "jsdoc2md ./src/main.js > ./docs/sorter.md" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/rBurgett/simple-sort.git" 19 | }, 20 | "keywords": [ 21 | "sort", 22 | "sorting", 23 | "locale", 24 | "international" 25 | ], 26 | "author": "Ryan Burgett", 27 | "license": "Apache-2.0", 28 | "bugs": { 29 | "url": "https://github.com/rBurgett/simple-sort/issues" 30 | }, 31 | "homepage": "https://github.com/rBurgett/simple-sort#readme", 32 | "devDependencies": { 33 | "babel-cli": "^6.11.4", 34 | "babel-core": "^6.11.4", 35 | "babel-preset-es2015": "^6.9.0", 36 | "babel-register": "^6.9.0", 37 | "eslint": "^3.1.1", 38 | "jsdoc": "^3.4.0", 39 | "mocha": "^2.5.3", 40 | "should": "^10.0.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | const CollatorPolyfill = function(locale) { 2 | this._locale = locale; 3 | }; 4 | CollatorPolyfill.prototype.compare = function(a, b) { 5 | return a.localeCompare(b, this._locale); 6 | }; 7 | 8 | /** 9 | * Constructs a sorter instance. 10 | * @constructor Sorter 11 | * @param {string} [locale] - the locale to sort by (e.g. 'en-US') 12 | */ 13 | const Sorter = function(locale) { 14 | this.intCol = (Intl && Intl.Collator) ? new Intl.Collator(locale) : new CollatorPolyfill(locale); 15 | }; 16 | 17 | Sorter.prototype._sort = function(arr, d) { 18 | return arr 19 | .concat() 20 | .sort((a, b) => a === b ? 0 : a > b ? (d * 1) : (d * -1)); 21 | }; 22 | 23 | /** 24 | * Sorts values in ascending order. 25 | * @param {Array} arr - Array of value to sort 26 | * @returns {Array} a new sorted Array 27 | */ 28 | Sorter.prototype.sortAsc = function(arr) { 29 | return this._sort(arr, 1); 30 | }; 31 | 32 | /** 33 | * Sorts values in descending order. 34 | * @param {Array} arr - Array of value to sort 35 | * @returns {Array} a new sorted Array 36 | */ 37 | Sorter.prototype.sortDes = function(arr) { 38 | return this._sort(arr, -1); 39 | }; 40 | 41 | Sorter.prototype._sortFunc = function(d) { 42 | return (a, b) => a === b ? 0 : a > b ? (d * 1) : (d * -1); 43 | }; 44 | 45 | /** 46 | * Constructs a function to sort values in ascending order. 47 | * @returns {Function} 48 | */ 49 | Sorter.prototype.sortAscFunc = function() { 50 | return this._sortFunc(1); 51 | }; 52 | 53 | /** 54 | * Constructs a function to sort values in descending order. 55 | * @returns {Function} 56 | */ 57 | Sorter.prototype.sortDesFunc = function() { 58 | return this._sortFunc(-1); 59 | }; 60 | 61 | Sorter.prototype._sortByProp = function(arr, prop, d) { 62 | return arr 63 | .concat() 64 | .sort((a, b) => a[prop] === b[prop] ? 0 : a[prop] > b[prop] ? (d * 1) : (d * -1)); 65 | }; 66 | 67 | /** 68 | * Sorts an Array of objects into ascending order by a certain property. 69 | * @param {Array} arr - Array of objects to sort 70 | * @param {string} prop - property to sort by 71 | * @returns {Array} a new sorted Array 72 | */ 73 | Sorter.prototype.sortByPropAsc = function(arr, prop) { 74 | return this._sortByProp(arr, prop, 1); 75 | }; 76 | 77 | /** 78 | * Sorts an Array of objects into descending order by a certain property. 79 | * @param {Array} arr - Array of objects to sort 80 | * @param {string} prop - property to sort by 81 | * @returns {Array} a new sorted Array 82 | */ 83 | Sorter.prototype.sortByPropDes = function(arr, prop) { 84 | return this._sortByProp(arr, prop, -1); 85 | }; 86 | 87 | Sorter.prototype._sortByPropFunc = function(prop, d) { 88 | return (a, b) => a[prop] === b[prop] ? 0 : a[prop] > b[prop] ? (d * 1) : (d * -1); 89 | }; 90 | 91 | /** 92 | * Constructs a function to sort values in ascending order by a certain property. 93 | * @param {string} prop - property to sort by 94 | * @returns {Function} 95 | */ 96 | Sorter.prototype.sortByPropAscFunc = function(prop) { 97 | return this._sortByPropFunc(prop, 1); 98 | }; 99 | 100 | /** 101 | * Constructs a function to sort values in descending order by a certain property. 102 | * @param {string} prop - property to sort by 103 | * @returns {Function} 104 | */ 105 | Sorter.prototype.sortByPropDesFunc = function(prop) { 106 | return this._sortByPropFunc(prop, -1); 107 | }; 108 | 109 | Sorter.prototype._localeSort = function(arr, d) { 110 | return arr 111 | .concat() 112 | .sort((a, b) => d * this.intCol.compare(a, b)); 113 | }; 114 | 115 | /** 116 | * Sorts values by locale in ascending order. 117 | * @param {Array} arr - Array of value to sort 118 | * @returns {Array} a new sorted Array 119 | */ 120 | Sorter.prototype.localeSortAsc = function(arr) { 121 | return this._localeSort(arr, 1); 122 | }; 123 | 124 | /** 125 | * Sorts values by locale in descending order. 126 | * @param {Array} arr - Array of value to sort 127 | * @returns {Array} a new sorted Array 128 | */ 129 | Sorter.prototype.localeSortDes = function(arr) { 130 | return this._localeSort(arr, -1); 131 | }; 132 | 133 | Sorter.prototype._localeSortFunc = function(d) { 134 | return (a, b) => d * this.intCol.compare(a, b); 135 | }; 136 | 137 | /** 138 | * Constructs a function to sort values by locale in ascending order. 139 | * @returns {Function} 140 | */ 141 | Sorter.prototype.localeSortAscFunc = function() { 142 | return this._localeSortFunc(1); 143 | }; 144 | 145 | /** 146 | * Constructs a function to sort values by locale in descending order. 147 | * @returns {Function} 148 | */ 149 | Sorter.prototype.localeSortDesFunc = function() { 150 | return this._localeSortFunc(-1); 151 | }; 152 | 153 | Sorter.prototype._localeSortByProp = function(arr, prop, d) { 154 | return arr 155 | .concat() 156 | .sort((a, b) => d * this.intCol.compare(a[prop], b[prop])); 157 | }; 158 | 159 | /** 160 | * Sorts an Array of objects by locale into ascending order by a certain property. 161 | * @param {Array} arr - Array of objects to sort 162 | * @param {string} prop - property to sort by 163 | * @returns {Array} a new sorted Array 164 | */ 165 | Sorter.prototype.localeSortByPropAsc = function(arr, prop) { 166 | return this._localeSortByProp(arr, prop, 1); 167 | }; 168 | 169 | /** 170 | * Sorts an Array of objects by locale into descending order by a certain property. 171 | * @param {Array} arr - Array of objects to sort 172 | * @param {string} prop - property to sort by 173 | * @returns {Array} a new sorted Array 174 | */ 175 | Sorter.prototype.localeSortByPropDes = function(arr, prop) { 176 | return this._localeSortByProp(arr, prop, -1); 177 | }; 178 | 179 | Sorter.prototype._localeSortByPropFunc = function(prop, d) { 180 | return (a, b) => d * this.intCol.compare(a[prop], b[prop]); 181 | }; 182 | 183 | /** 184 | * Constructs a function to sort values by locale in ascending order by a certain property. 185 | * @param {string} prop - property to sort by 186 | * @returns {Function} 187 | */ 188 | Sorter.prototype.localeSortByPropAscFunc = function(prop) { 189 | return this._localeSortByPropFunc(prop, 1); 190 | }; 191 | 192 | /** 193 | * Constructs a function to sort values by locale in descending order by a certain property. 194 | * @param {string} prop - property to sort by 195 | * @returns {Function} 196 | */ 197 | Sorter.prototype.localeSortByPropDesFunc = function(prop) { 198 | return this._localeSortByPropFunc(prop, -1); 199 | }; 200 | 201 | export default Sorter; 202 | -------------------------------------------------------------------------------- /test/sorter-tests.js: -------------------------------------------------------------------------------- 1 | // import fs from 'fs'; 2 | // import path from 'path'; 3 | import 'should'; 4 | 5 | import Sorter from '../src/main.js'; 6 | 7 | const myStrArr = ['c','e','a','b','d','e','f']; 8 | const myNumArr = [1,5,7,4,3,9,7]; 9 | const objNumArr = [{num:1},{num:5},{num:7},{num:4},{num:3},{num:9},{num:7}]; 10 | const objStrArr = [{str:'c'},{str:'e'},{str:'a'},{str:'b'},{str:'d'},{str:'e'},{str:'f'}]; 11 | 12 | describe('Sorter', () => { 13 | 14 | const sorter = new Sorter('en'); 15 | 16 | it('should be a function', () => { 17 | Sorter.should.be.a.Function(); 18 | }); 19 | 20 | describe('sorting methods', () => { 21 | describe('sortAsc method', () => { 22 | it('should sort an array of values into ascending order', () => { 23 | sorter.sortAsc(myNumArr).should.eql([1,3,4,5,7,7,9]); 24 | }); 25 | }); 26 | 27 | describe('sortDes method', () => { 28 | it('should sort an array of values into descending order', () => { 29 | sorter.sortDes(myNumArr).should.eql([9,7,7,5,4,3,1]); 30 | }); 31 | }); 32 | 33 | describe('sortByPropAsc method', () => { 34 | it('should sort an array of object into ascending order by a certain property', () => { 35 | sorter.sortByPropAsc(objNumArr, 'num').should.eql([{num:1},{num:3},{num:4},{num:5},{num:7},{num:7},{num:9}]); 36 | }); 37 | }); 38 | 39 | describe('sortDes method', () => { 40 | it('should sort an array of object into descending order by a certain property', () => { 41 | sorter.sortByPropDes(objNumArr, 'num').should.eql([{num:9},{num:7},{num:7},{num:5},{num:4},{num:3},{num:1}]); 42 | }); 43 | }); 44 | 45 | describe('localeSortAsc method', () => { 46 | it('should sort an array of values into ascending order', () => { 47 | sorter.localeSortAsc(myStrArr).should.eql(['a','b','c','d','e','e','f']); 48 | }); 49 | }); 50 | 51 | describe('localeSortDes method', () => { 52 | it('should sort an array of values into descending order', () => { 53 | sorter.localeSortDes(myStrArr).should.eql(['f','e','e','d','c','b','a']); 54 | }); 55 | }); 56 | 57 | describe('localeSortByPropAsc method', () => { 58 | it('should sort an array of objects into ascending order by a certain property', () => { 59 | sorter.localeSortByPropAsc(objStrArr, 'str').should.eql([{str:'a'},{str:'b'},{str:'c'},{str:'d'},{str:'e'},{str:'e'},{str:'f'}]); 60 | }); 61 | }); 62 | 63 | describe('localeSortByPropDes method', () => { 64 | it('should sort an array of objects into descending order by a certain property', () => { 65 | sorter.localeSortByPropDes(objStrArr, 'str').should.eql([{str:'f'},{str:'e'},{str:'e'},{str:'d'},{str:'c'},{str:'b'},{str:'a'}]); 66 | }); 67 | }); 68 | }); 69 | 70 | describe('sort function returning methods', () => { 71 | describe('sortAscFunc method', () => { 72 | it('should return a function', () => { 73 | sorter.sortAscFunc().should.be.a.Function(); 74 | }); 75 | describe('the returned function', () => { 76 | it('should be able to sort an array of values into ascending order', () => { 77 | myNumArr 78 | .concat() 79 | .sort(sorter.sortAscFunc()).should.eql([1,3,4,5,7,7,9]); 80 | }); 81 | }); 82 | }); 83 | 84 | describe('sortDesFunc method', () => { 85 | it('should return a function', () => { 86 | sorter.sortDesFunc().should.be.a.Function(); 87 | }); 88 | describe('the returned function', () => { 89 | it('should be able to sort an array of values into descending order', () => { 90 | myNumArr 91 | .concat() 92 | .sort(sorter.sortDesFunc()).should.eql([9,7,7,5,4,3,1]); 93 | }); 94 | }); 95 | }); 96 | 97 | describe('sortByPropAscFunc method', () => { 98 | it('should return a function', () => { 99 | sorter.sortByPropAscFunc('num').should.be.a.Function(); 100 | }); 101 | describe('the returned function', () => { 102 | it('should be able to sort an array of objects into ascending order by a certain property', () => { 103 | objNumArr 104 | .concat() 105 | .sort(sorter.sortByPropAscFunc('num')).should.eql([{num:1},{num:3},{num:4},{num:5},{num:7},{num:7},{num:9}]); 106 | }); 107 | }); 108 | }); 109 | 110 | describe('sortByPropDesFunc method', () => { 111 | it('should return a function', () => { 112 | sorter.sortByPropDesFunc('num').should.be.a.Function(); 113 | }); 114 | describe('the returned function', () => { 115 | it('should be able to sort an array of objects into descending order by a certain property', () => { 116 | objNumArr 117 | .concat() 118 | .sort(sorter.sortByPropDesFunc('num')).should.eql([{num:9},{num:7},{num:7},{num:5},{num:4},{num:3},{num:1}]); 119 | }); 120 | }); 121 | }); 122 | 123 | describe('localeSortAscFunc method', () => { 124 | it('should return a function', () => { 125 | sorter.localeSortAscFunc().should.be.a.Function(); 126 | }); 127 | describe('the returned function', () => { 128 | it('should be able to sort an array of values into ascending order', () => { 129 | myStrArr 130 | .concat() 131 | .sort(sorter.localeSortAscFunc()).should.eql(['a','b','c','d','e','e','f']); 132 | }); 133 | }); 134 | }); 135 | 136 | describe('localeSortDesFunc method', () => { 137 | it('should return a function', () => { 138 | sorter.localeSortDesFunc().should.be.a.Function(); 139 | }); 140 | describe('the returned function', () => { 141 | it('should be able to sort an array of values into descending order', () => { 142 | myStrArr 143 | .concat() 144 | .sort(sorter.localeSortDesFunc()).should.eql(['f','e','e','d','c','b','a']); 145 | }); 146 | }); 147 | }); 148 | 149 | describe('localeSortByPropAscFunc method', () => { 150 | it('should return a function', () => { 151 | sorter.localeSortByPropAscFunc().should.be.a.Function(); 152 | }); 153 | describe('the returned function', () => { 154 | it('should be able to sort an array of values into ascending order', () => { 155 | objStrArr 156 | .concat() 157 | .sort(sorter.localeSortByPropAscFunc('str')).should.eql([{str:'a'},{str:'b'},{str:'c'},{str:'d'},{str:'e'},{str:'e'},{str:'f'}]); 158 | }); 159 | }); 160 | }); 161 | 162 | describe('localeSortByPropDesFunc method', () => { 163 | it('should return a function', () => { 164 | sorter.localeSortByPropDesFunc().should.be.a.Function(); 165 | }); 166 | describe('the returned function', () => { 167 | it('should be able to sort an array of values into descending order', () => { 168 | objStrArr 169 | .concat() 170 | .sort(sorter.localeSortByPropDesFunc('str')).should.eql([{str:'f'},{str:'e'},{str:'e'},{str:'d'},{str:'c'},{str:'b'},{str:'a'}]); 171 | }); 172 | }); 173 | }); 174 | 175 | }); 176 | 177 | // describe('speed comparison with localeCompare()', function() { 178 | // 179 | // this.timeout(30000); 180 | // 181 | // const bigWordArray = JSON.parse(fs.readFileSync(path.join('test', 'words.json'), 'utf8')); 182 | // 183 | // describe('localeCompare()', () => { 184 | // it('should take a long time', () => { 185 | // const sortedWordArray = bigWordArray 186 | // .concat() 187 | // .sort((a, b) => a.localeCompare(b, 'en')); 188 | // sortedWordArray.should.be.an.Array(); 189 | // }); 190 | // }); 191 | // 192 | // describe('localeSortAscFunc', () => { 193 | // it('should take a much shorter time', () => { 194 | // const sortedWordArray = bigWordArray 195 | // .concat() 196 | // .sort(sorter.localeSortAscFunc()); 197 | // sortedWordArray.should.be.an.Array(); 198 | // }); 199 | // }); 200 | // 201 | // }); 202 | 203 | }); 204 | --------------------------------------------------------------------------------