70 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| Object.defineProperty(exports, '__esModule', {
 | |
|   value: true,
 | |
| });
 | |
| exports.naturalCompare = naturalCompare;
 | |
| 
 | |
| /**
 | |
|  * Returns a number indicating whether a reference string comes before, or after,
 | |
|  * or is the same as the given string in natural sort order.
 | |
|  *
 | |
|  * See: https://en.wikipedia.org/wiki/Natural_sort_order
 | |
|  *
 | |
|  */
 | |
| function naturalCompare(aStr, bStr) {
 | |
|   let aIndex = 0;
 | |
|   let bIndex = 0;
 | |
| 
 | |
|   while (aIndex < aStr.length && bIndex < bStr.length) {
 | |
|     let aChar = aStr.charCodeAt(aIndex);
 | |
|     let bChar = bStr.charCodeAt(bIndex);
 | |
| 
 | |
|     if (isDigit(aChar) && isDigit(bChar)) {
 | |
|       let aNum = 0;
 | |
| 
 | |
|       do {
 | |
|         ++aIndex;
 | |
|         aNum = aNum * 10 + aChar - DIGIT_0;
 | |
|         aChar = aStr.charCodeAt(aIndex);
 | |
|       } while (isDigit(aChar) && aNum > 0);
 | |
| 
 | |
|       let bNum = 0;
 | |
| 
 | |
|       do {
 | |
|         ++bIndex;
 | |
|         bNum = bNum * 10 + bChar - DIGIT_0;
 | |
|         bChar = bStr.charCodeAt(bIndex);
 | |
|       } while (isDigit(bChar) && bNum > 0);
 | |
| 
 | |
|       if (aNum < bNum) {
 | |
|         return -1;
 | |
|       }
 | |
| 
 | |
|       if (aNum > bNum) {
 | |
|         return 1;
 | |
|       }
 | |
|     } else {
 | |
|       if (aChar < bChar) {
 | |
|         return -1;
 | |
|       }
 | |
| 
 | |
|       if (aChar > bChar) {
 | |
|         return 1;
 | |
|       }
 | |
| 
 | |
|       ++aIndex;
 | |
|       ++bIndex;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return aStr.length - bStr.length;
 | |
| }
 | |
| 
 | |
| const DIGIT_0 = 48;
 | |
| const DIGIT_9 = 57;
 | |
| 
 | |
| function isDigit(code) {
 | |
|   return !isNaN(code) && DIGIT_0 <= code && code <= DIGIT_9;
 | |
| }
 |