Skip to content

Instantly share code, notes, and snippets.

@vnugent
Last active September 21, 2020 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vnugent/bf5311942252f0e25e54c5234a003e98 to your computer and use it in GitHub Desktop.
Save vnugent/bf5311942252f0e25e54c5234a003e98 to your computer and use it in GitHub Desktop.
Yosemite Decimal System validator & comparator
// match 5.0 up to 5.15 including + and -. Example: 5.10+ or 5.12-
const REGEX_5_X = RegExp(/^5\.([0-9]|1[0-5])([+-]?)$/);
// match 5.10x to 5.15x. Example: 5.12c
const REGEX_5_10_LETTER = RegExp(/^5\.(1[0-5])([abcd])(?:\/[abcd])?$/);
/**
* Test if a grade string is in valid format
* @param {yds} grade
*/
export const is_valid = (grade) => get_weight(grade) !== -99;
export const get_weight = (grade) => {
if (grade === "3rd") return -3;
if (grade === "4th") return -2;
if (grade === "Easy 5th") return -1;
const m1 = REGEX_5_X.exec(grade);
const m2 = REGEX_5_10_LETTER.exec(grade);
if (m1 && m1.length > 1) {
// 5.10- ==> 5.10a
// 5.10+ ==> 5.10c
// 5.10 ==> 5.10c
const bias = m1[2] === "-" ? 1 : 3;
return Number(m1[1]) * 10 + bias;
} else if (m2 && m2.length > 1) {
const letter = m2.length > 2 ? m2[2].charCodeAt(0) - 96 : 0;
return Number(m2[1]) * 10 + letter;
}
return -99;
};
/**
* YDS comparator. Letter grade convention:
* 5.10- == 5.10a
* 5.10 == 5.10c
* 5.10c < 5.10d
* 5.10d < 5.11-
*
* @param a
* @param b
*/
export const comparator = (a, b) => {
const w_a = get_weight(a);
const w_b = get_weight(b);
if (w_a < w_b) return -1;
if (w_a > w_b) return 1;
return 0;
};
@vnugent
Copy link
Author

vnugent commented Sep 21, 2020

Live codesandbox

How to sort a list

import { comparator } from "./yds-utils.js"

unsorted = ["5.11-",  "5.10d", "5.10" ,"5.10a", "5.8", "5.9+", "5.15"]

console.log(unsorted.sort(comparator))

Result ==>

5.8

5.9+

5.10a

5.10

5.10d

5.11-

5.15

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment