Skip to content

Instantly share code, notes, and snippets.

@DarrenSem
Created July 10, 2022 21:41
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 DarrenSem/4ab1f925b978838bd7cef0919bd22660 to your computer and use it in GitHub Desktop.
Save DarrenSem/4ab1f925b978838bd7cef0919bd22660 to your computer and use it in GitHub Desktop.
ordinal.js - one-liner returns ordinal(1)="1st", (2)="2nd", (3)="3rd", (11)="11th", (21)="21st", (111)="111th", (121)="121st", etc.
// ordinal.js - one-liner returns ordinal(1)="1st", (2)="2nd", (3)="3rd", (11)="11th", (21)="21st", (111)="111th", (121)="121st", etc.
let ordinal = num => `${num}${[, "st", "nd", "rd"][ (num % 100 < 11 || num % 100 > 13) && (num % 10) ] || "th"}`;
// ^ Final Answer. (below = the story of how I got there...)
"use strict";// ordinal.js - one-liner returns ordinal(1)="1st", (2)="2nd", (3)="3rd", (11)="11th", (21)="21st", (111)="111th", (121)="121st", etc.
let ordinal = num => `${num}${[, "st", "nd", "rd"][ (num % 100 < 11 || num % 100 > 13) && (num % 10) ] || "th"}`;
// ^ Final Answer. (below = the story of how I got there...)
"use strict";
console.clear();
let filledArray = (lo, hi, func) => Array(hi - lo + 1).fill().map((el, index) => (func || ((index, start, end) => start + index))(index, lo, hi)); // OLD: { const result = []; for(let i = Math.abs(lo); i <= Math.abs(hi), i++) { result.push(i) }; return result; }
let LO = -25, HI = 125, ordinal_test = (func, lo, hi) => filledArray(lo, hi).map(el => func(el));
let ordinalOld = (num, z, y) => (
z = z = Number(num) || 0
, y = z % 10
, `${z}${(parseInt(z % 100 / 10) === 1) ? 'th' : (y === 1) ? 'st' : (y === 2) ? 'nd' : (y === 3) ? 'rd' : 'th'}`
); // concise logic based on moment.js ("original" and/or "newer") https://github.com/moment/moment/blob/master/src/locale/x-pseudo.js#L55 [originally https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.js#L4048] // because certain other examples fail on [ (111) = 111st, (112) = 112nd, (113) = 113th ] -- for example https://www.w3resource.com/javascript-exercises/javascript-date-exercise-23.php#comment-3494442751 = var result = `${z}${z < 11 || z > 13 ? ["st", "nd", "rd", "th"][Math.min((z - 1) % 10, 3)] : "th"}` // and SO DOES THIS: var result = `${z}${z % 10 == 1 && z != 11 ? "st" : (z % 10 == 2 && z != 12 ? "nd" : (z % 10 == 3 && z != 13 ? "rd" : "th"))}` // z = {1:"st", 2:"nd", 3:"rd"}; return `${n}${z[num(n)] || "th"}`
let resultsOrdinalOld = ordinal_test(ordinalOld, LO, HI);
/*
ordinal : function (number) { // moment.js "original"
var b = number % 10,
output = (toInt(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
};
ordinal: function (number) { // moment.js "newer"
var b = number % 10,
output = ~~((number % 100) / 10) === 1 ? 'th' // ~~ = Bitwise_NOT twice: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT
: b === 1 ? 'st'
: b === 2 ? 'nd'
: b === 3 ? 'rd'
: 'th';
return number + output;
};
*/
let ordinalVitest = num => { // via https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/integrations/chai/jest-expect.ts#L340
const j = num % 10, k = num % 100;
if (j === 1 && k !== 11)return `${num}st`;
if (j === 2 && k !== 12)return `${num}nd`;
if (j === 3 && k !== 13)return `${num}rd`;
return `${num}th`;
};
let resultsOrdinalVitest = ordinal_test(ordinalVitest, LO, HI);
console.log("ordinalOld === ordinalVitest?", JSON.stringify(resultsOrdinalOld) === JSON.stringify(resultsOrdinalVitest));
let ordinalVitestModified = (num, j, k) => (
j = num % 10, k = num % 100
, (j === 1 && k !== 11) ? `${num}st`
: (j === 2 && k !== 12) ? `${num}nd`
: (j === 3 && k !== 13) ? `${num}rd`
: `${num}th`
);
let resultsOrdinalVitestModified = ordinal_test(ordinalVitestModified, LO, HI);
console.log("ordinalVitest === ordinalVitestModified?", JSON.stringify(resultsOrdinalVitest) === JSON.stringify(resultsOrdinalVitestModified));
let ordinalAlmostFinal = num => num + ( // a pattern became obvious after this...
(num % 10 === 1 && num % 100 !== 11) ? "st"
: (num % 10 === 2 && num % 100 !== 12) ? "nd"
: (num % 10 === 3 && num % 100 !== 13) ? "rd"
: "th"
);
let resultsOrdinalAlmostFinal = ordinal_test(ordinalAlmostFinal, LO, HI);
console.log("ordinalVitestModified === ordinalAlmostFinal?", JSON.stringify(resultsOrdinalVitestModified) === JSON.stringify(resultsOrdinalAlmostFinal));
let ordinalFinal = num => `${num}${[, "st", "nd", "rd"][ (num % 100 < 11 || num % 100 > 13) && (num % 10) ] || "th"}`;
let resultsOrdinalFinal = ordinal_test(ordinalFinal, LO, HI);
console.log(resultsOrdinalFinal);
console.log("ordinalFinal === ordinalVitestModified?", JSON.stringify(resultsOrdinalFinal) === JSON.stringify(resultsOrdinalVitestModified));
console.clear();
let filledArray = (lo, hi, func) => Array(hi - lo + 1).fill().map((el, index) => (func || ((index, start, end) => start + index))(index, lo, hi)); // OLD: { const result = []; for(let i = Math.abs(lo); i <= Math.abs(hi), i++) { result.push(i) }; return result; }
let LO = -25, HI = 125, ordinal_test = (func, lo, hi) => filledArray(lo, hi).map(el => func(el));
let ordinalOld = (num, z, y) => (
z = z = Number(num) || 0
, y = z % 10
, `${z}${(parseInt(z % 100 / 10) === 1) ? 'th' : (y === 1) ? 'st' : (y === 2) ? 'nd' : (y === 3) ? 'rd' : 'th'}`
); // concise logic based on moment.js ("original" and/or "newer") https://github.com/moment/moment/blob/master/src/locale/x-pseudo.js#L55 [originally https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.js#L4048] // because certain other examples fail on [ (111) = 111st, (112) = 112nd, (113) = 113th ] -- for example https://www.w3resource.com/javascript-exercises/javascript-date-exercise-23.php#comment-3494442751 = var result = `${z}${z < 11 || z > 13 ? ["st", "nd", "rd", "th"][Math.min((z - 1) % 10, 3)] : "th"}` // and SO DOES THIS: var result = `${z}${z % 10 == 1 && z != 11 ? "st" : (z % 10 == 2 && z != 12 ? "nd" : (z % 10 == 3 && z != 13 ? "rd" : "th"))}` // z = {1:"st", 2:"nd", 3:"rd"}; return `${n}${z[num(n)] || "th"}`
let resultsOrdinalOld = ordinal_test(ordinalOld, LO, HI);
/*
ordinal : function (number) { // moment.js "original"
var b = number % 10,
output = (toInt(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
};
ordinal: function (number) { // moment.js "newer"
var b = number % 10,
output = ~~((number % 100) / 10) === 1 ? 'th' // ~~ = Bitwise_NOT twice: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT
: b === 1 ? 'st'
: b === 2 ? 'nd'
: b === 3 ? 'rd'
: 'th';
return number + output;
};
*/
let ordinalVitest = num => { // via https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/integrations/chai/jest-expect.ts#L340
const j = num % 10, k = num % 100;
if (j === 1 && k !== 11)return `${num}st`;
if (j === 2 && k !== 12)return `${num}nd`;
if (j === 3 && k !== 13)return `${num}rd`;
return `${num}th`;
};
let resultsOrdinalVitest = ordinal_test(ordinalVitest, LO, HI);
console.log("ordinalOld === ordinalVitest?", JSON.stringify(resultsOrdinalOld) === JSON.stringify(resultsOrdinalVitest));
let ordinalVitestModified = (num, j, k) => (
j = num % 10, k = num % 100
, (j === 1 && k !== 11) ? `${num}st`
: (j === 2 && k !== 12) ? `${num}nd`
: (j === 3 && k !== 13) ? `${num}rd`
: `${num}th`
);
let resultsOrdinalVitestModified = ordinal_test(ordinalVitestModified, LO, HI);
console.log("ordinalVitest === ordinalVitestModified?", JSON.stringify(resultsOrdinalVitest) === JSON.stringify(resultsOrdinalVitestModified));
let ordinalAlmostFinal = num => num + ( // a pattern became obvious after this...
(num % 10 === 1 && num % 100 !== 11) ? "st"
: (num % 10 === 2 && num % 100 !== 12) ? "nd"
: (num % 10 === 3 && num % 100 !== 13) ? "rd"
: "th"
);
let resultsOrdinalAlmostFinal = ordinal_test(ordinalAlmostFinal, LO, HI);
console.log("ordinalVitestModified === ordinalAlmostFinal?", JSON.stringify(resultsOrdinalVitestModified) === JSON.stringify(resultsOrdinalAlmostFinal));
let ordinalFinal = num => `${num}${[, "st", "nd", "rd"][ (num % 100 < 11 || num % 100 > 13) && (num % 10) ] || "th"}`;
let resultsOrdinalFinal = ordinal_test(ordinalFinal, LO, HI);
console.log(resultsOrdinalFinal);
console.log("ordinalFinal === ordinalVitestModified?", JSON.stringify(resultsOrdinalFinal) === JSON.stringify(resultsOrdinalVitestModified));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment