给一个数字加上st, nd, rd和th(序数)后缀

我想动态生成基于当前一天的文本字符串。因此,例如,如果这是第一天,那么我希望我的代码生成=“Its the <dynamic>1*<dynamic string></dynamic string>*</dynamic>”。

总共有12天,所以我做了以下事情:

  1. 我设置了一个for循环,循环12天。

  2. 在我的html中,我给了我的元素一个唯一的id,用它来瞄准它,如下所示:

    <h1 id="dynamicTitle" class="CustomFont leftHeading shadow">On The <span></span> <em>of rest of generic text</em></h1>
    
  3. Then, inside my for loop I have the following code:

    $("#dynamicTitle span").html(i);
    var day = i;
    if (day == 1) {
    day = i + "st";
    } else if (day == 2) {
    day = i + "nd"
    } else if (day == 3) {
    day = i + "rd"
    }
    

UPDATE

This is the entire for loop as requested:

$(document).ready(function () {
for (i = 1; i <= 12; i++) {
var classy = "";
if (daysTilDate(i + 19) > 0) {
classy = "future";
$("#Day" + i).addClass(classy);
$("#mainHeading").html("");
$("#title").html("");
$("#description").html("");
} else if (daysTilDate(i + 19) < 0) {
classy = "past";
$("#Day" + i).addClass(classy);
$("#title").html("");
$("#description").html("");
$("#mainHeading").html("");
$(".cta").css('display', 'none');
$("#Day" + i + " .prizeLink").attr("href", "" + i + ".html");
} else {
classy = "current";
$("#Day" + i).addClass(classy);
$("#title").html(headings[i - 1]);
$("#description").html(descriptions[i - 1]);
$(".cta").css('display', 'block');
$("#dynamicImage").attr("src", ".." + i + ".jpg");
$("#mainHeading").html("");
$(".claimPrize").attr("href", "" + i + ".html");
$("#dynamicTitle span").html(i);
var day = i;
if (day == 1) {
day = i + "st";
} else if (day == 2) {
day = i + "nd"
} else if (day == 3) {
day = i + "rd"
} else if (day) {
}
}
}
150279 次浏览

规则如下:

  • St用于以1结尾的数字(例如1st,发音为first)
  • Nd与以2结尾的数字连用(例如92nd,发音为ninety-second)
  • Rd与以3结尾的数字连用(例如33rd,发音为33third)
  • 作为上述规则的例外,所有以11、12或13结尾的“青少年”数字都使用-th(例如,11,发音为111,112, 读作一百个[和]十二)
  • Th用于所有其他数字(例如:9th,发音为ninth)。

以下JavaScript代码(在14年6月重写)实现了这一点:

function ordinal_suffix_of(i) {
var j = i % 10,
k = i % 100;
if (j == 1 && k != 11) {
return i + "st";
}
if (j == 2 && k != 12) {
return i + "nd";
}
if (j == 3 && k != 13) {
return i + "rd";
}
return i + "th";
}

0-115之间数字的示例输出:

  0  0th
1  1st
2  2nd
3  3rd
4  4th
5  5th
6  6th
7  7th
8  8th
9  9th
10  10th
11  11th
12  12th
13  13th
14  14th
15  15th
16  16th
17  17th
18  18th
19  19th
20  20th
21  21st
22  22nd
23  23rd
24  24th
25  25th
26  26th
27  27th
28  28th
29  29th
30  30th
31  31st
32  32nd
33  33rd
34  34th
35  35th
36  36th
37  37th
38  38th
39  39th
40  40th
41  41st
42  42nd
43  43rd
44  44th
45  45th
46  46th
47  47th
48  48th
49  49th
50  50th
51  51st
52  52nd
53  53rd
54  54th
55  55th
56  56th
57  57th
58  58th
59  59th
60  60th
61  61st
62  62nd
63  63rd
64  64th
65  65th
66  66th
67  67th
68  68th
69  69th
70  70th
71  71st
72  72nd
73  73rd
74  74th
75  75th
76  76th
77  77th
78  78th
79  79th
80  80th
81  81st
82  82nd
83  83rd
84  84th
85  85th
86  86th
87  87th
88  88th
89  89th
90  90th
91  91st
92  92nd
93  93rd
94  94th
95  95th
96  96th
97  97th
98  98th
99  99th
100  100th
101  101st
102  102nd
103  103rd
104  104th
105  105th
106  106th
107  107th
108  108th
109  109th
110  110th
111  111th
112  112th
113  113th
114  114th
115  115th

你只有12天?我想让它只是一个简单的查找数组:

var suffixes = ['','st','nd','rd','th','th','th','th','th','th','th','th','th'];

然后

var i = 2;
var day = i + suffixes[i]; // result: '2nd'

var i = 8;
var day = i + suffixes[i]; // result: '8th'

前几天我写了这个简单的函数。虽然对于一个日期你不需要更大的数字,但这也可以满足更高的数值(1013th, 36021等等……)

var fGetSuffix = function(nPos){


var sSuffix = "";


switch (nPos % 10){
case 1:
sSuffix = (nPos % 100 === 11) ? "th" : "st";
break;
case 2:
sSuffix = (nPos % 100 === 12) ? "th" : "nd";
break;
case 3:
sSuffix = (nPos % 100 === 13) ? "th" : "rd";
break;
default:
sSuffix = "th";
break;
}


return sSuffix;
};

通过将数字分割成一个数组并反转,我们可以很容易地使用array[0]array[1]检查数字的最后两位。

如果一个数字是在青少年array[1] = 1 ,它需要"th"。

function getDaySuffix(num)
{
var array = ("" + num).split("").reverse(); // E.g. 123 = array("3","2","1")
    

if (array[1] != "1") { // Number is not in the teens
switch (array[0]) {
case "1": return "st";
case "2": return "nd";
case "3": return "rd";
}
}
    

return "th";
}

我写了这个函数来解决这个问题:

// this is for adding the ordinal suffix, turning 1, 2 and 3 into 1st, 2nd and 3rd
Number.prototype.addSuffix=function(){
var n=this.toString().split('.')[0];
var lastDigits=n.substring(n.length-2);
//add exception just for 11, 12 and 13
if(lastDigits==='11' || lastDigits==='12' || lastDigits==='13'){
return this+'th';
}
switch(n.substring(n.length-1)){
case '1': return this+'st';
case '2': return this+'nd';
case '3': return this+'rd';
default : return this+'th';
}
};

有了这个,你可以把.addSuffix()放在任何数字上,它会得到你想要的结果。例如:

var number=1234;
console.log(number.addSuffix());
// console will show: 1234th

function ordsfx(a){return["th","st","nd","rd"][(a=~~(a<0?-a:a)%100)>10&&a<14||(a%=10)>3?0:a]}

参见https://gist.github.com/furf/986113#file-annotated-js注释版本

就像效用函数应该做的那样,简短、可爱、高效。适用于任何有符号/无符号整数/浮点数。(尽管我无法想象有必要对浮点数进行ordinalize)

function getSuffix(n) {return n < 11 || n > 13 ? ['st', 'nd', 'rd', 'th'][Math.min((n - 1) % 10, 3)] : 'th'}

.
<p>31<sup>st</sup> March 2015</p>

You can use

1<sup>st</sup> 2<sup>nd</sup> 3<sup>rd</sup> 4<sup>th</sup>

for positioning the suffix

Shopify

function getNumberWithOrdinal(n) {
var s = ["th", "st", "nd", "rd"],
v = n % 100;
return n + (s[(v - 20) % 10] || s[v] || s[0]);
}


[-4,-1,0,1,2,3,4,10,11,12,13,14,20,21,22,100,101,111].forEach(
n => console.log(n + ' -> ' + getNumberWithOrdinal(n))
);

序数后缀的最小一行方法

function nth(n){return["st","nd","rd"][((n+90)%100-10)%10-1]||"th"}

(这是为正整数,参见下面的其他变化)

解释

从后缀为["st", "nd", "rd"]的数组开始。我们希望将以1,2,3结尾的整数(但不以11,12,13结尾)映射到索引0,1,2。

其他整数(包括以11、12、13结尾的整数)可以映射到任何其他整数——数组中没有找到的索引将计算为undefined。这在javascript中是错误的,通过使用逻辑或(|| "th"),表达式将为这些整数返回"th",这正是我们想要的。

表达式((n + 90) % 100 - 10) % 10 - 1进行映射。分解一下:

  • (n + 90) % 100:该表达式接受输入整数−10 mod 100,将10映射到0,…99到89,0到90,……, 9到99。现在,以11、12、13结尾的整数位于下端(映射到1,2,3)。
  • - 10:现在10映射到−10,19映射到−1,99映射到79,0映射到80,…9岁到89岁。以11、12、13结尾的整数映射为负整数(−9、−8、−7)。
  • % 10:现在所有以1,2,3结尾的整数都映射为1,2,3。所有其他整数都映射到其他整数(11、12、13仍然映射到−9、−8、−7)。
  • - 1:减去1给出1,2,3到0,1,2的最终映射。

验证它的工作

function nth(n){return["st","nd","rd"][((n+90)%100-10)%10-1]||"th"}


//test integers from 1 to 124
for(var r = [], i = 1; i < 125; i++) r.push(i + nth(i));


//output result
document.getElementById('result').innerHTML = r.join('<br>');
<div id="result"></div>

Variations

Allowing negative integers:

function nth(n){return["st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10-1]||"th"}

function nth(n){return["st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10-1]||"th"}


//test integers from 15 to -124
for(var r = [], i = 15; i > -125; i--) r.push(i + nth(i));


//output result
document.getElementById('result').innerHTML = r.join('<br>');
<div id="result"></div>

In ES6 fat arrow syntax (anonymous function):

n=>["st","nd","rd"][(((n<0?-n:n)+90)%100-10)%10-1]||"th"

这是另一种选择。

function getOrdinalSuffix(day) {
        

if(/^[2-3]?1$/.test(day)){
return 'st';
} else if(/^[2-3]?2$/.test(day)){
return 'nd';
} else if(/^[2-3]?3$/.test(day)){
return 'rd';
} else {
return 'th';
}
        

}
    

console.log(getOrdinalSuffix('1'));
console.log(getOrdinalSuffix('13'));
console.log(getOrdinalSuffix('22'));
console.log(getOrdinalSuffix('33'));

注意到青少年的例外了吗?青少年都很幼稚!

编辑:忘了11号和12号吧

序数函数的另一个版本可以如下所示:

function toCardinal(num) {
var ones = num % 10;
var tens = num % 100;


if (tens < 11 || tens > 13) {
switch (ones) {
case 1:
return num + "st";
case 2:
return num + "nd";
case 3:
return num + "rd";
}
}


return num + "th";
}

变量的命名更加明确,使用驼峰大小写约定,并且可能更快。

我想为这个问题提供一个功能性的答案,以补充现有的答案:

const ordinalSuffix = ['st', 'nd', 'rd']
const addSuffix = n => n + (ordinalSuffix[(n - 1) % 10] || 'th')
const numberToOrdinal = n => `${n}`.match(/1\d$/) ? n + 'th' : addSuffix(n)

我们已经创建了一个特殊值的数组,重要的是要记住数组有一个从零开始的索引,因此ordinalSuffix[0]等于'st'。

我们的函数numberToOrdinal检查数字是否以十位数结尾,在这种情况下,将数字附加为'th',因为所有的数字序数都是'th'。如果数字不是teen,我们将数字传递给addSuffix,它将数字添加到序数中,这是由如果数字- 1(因为我们使用的是零为基础的索引)mod 10余数为2或更少,则从数组中取出,否则是'th'。

样例输出:

numberToOrdinal(1) // 1st
numberToOrdinal(2) // 2nd
numberToOrdinal(3) // 3rd
numberToOrdinal(4) // 4th
numberToOrdinal(5) // 5th
numberToOrdinal(6) // 6th
numberToOrdinal(7) // 7th
numberToOrdinal(8) // 8th
numberToOrdinal(9) // 9th
numberToOrdinal(10) // 10th
numberToOrdinal(11) // 11th
numberToOrdinal(12) // 12th
numberToOrdinal(13) // 13th
numberToOrdinal(14) // 14th
numberToOrdinal(101) // 101st

以前我为我的东西做的…

function convertToOrdinal(number){
if (number !=1){
var numberastext = number.ToString();
var endchar = numberastext.Substring(numberastext.Length - 1);
if (number>9){
var secondfromendchar = numberastext.Substring(numberastext.Length - 1);
secondfromendchar = numberastext.Remove(numberastext.Length - 1);
}
var suffix = "th";
var digit = int.Parse(endchar);
switch (digit){
case 3:
if(secondfromendchar != "1"){
suffix = "rd";
break;
}
case 2:
if(secondfromendchar != "1"){
suffix = "nd";
break;
}
case 1:
if(secondfromendchar != "1"){
suffix = "st";
break;
}
default:
suffix = "th";
break;
}
return number+suffix+" ";
} else {
return;
}
}

强烈推荐优秀的date-fns库。快速,模块化,不可变,适用于标准日期。

import * as DateFns from 'date-fns';


const ordinalInt = DateFns.format(someInt, 'do');

参见date-fns docs: https://date-fns.org/v2.0.0-alpha.9/docs/format

我为更大的数字和所有测试用例写了这个函数

function numberToOrdinal(num) {
if (num === 0) {
return '0'
};
let i = num.toString(), j = i.slice(i.length - 2), k = i.slice(i.length - 1);
if (j >= 10 && j <= 20) {
return (i + 'th')
} else if (j > 20 && j < 100) {
if (k == 1) {
return (i + 'st')
} else if (k == 2) {
return (i + 'nd')
} else if (k == 3) {
return (i + 'rd')
} else {
return (i + 'th')
}
} else if (j == 1) {
return (i + 'st')
} else if (j == 2) {
return (i + 'nd')
} else if (j == 3) {
return (i + 'rd')
} else {
return (i + 'th')
}
}

我强烈推荐这本书,它超级简单易懂。希望有帮助?

  • 它避免使用负整数,即小于1的数字并返回false
  • 如果输入为0,则返回0
function numberToOrdinal(n) {


let result;


if(n < 0){
return false;
}else if(n === 0){
result = "0";
}else if(n > 0){


let nToString = n.toString();
let lastStringIndex = nToString.length-1;
let lastStringElement = nToString[lastStringIndex];


if( lastStringElement == "1" && n % 100 !== 11 ){
result = nToString + "st";
}else if( lastStringElement == "2" && n % 100 !== 12 ){
result = nToString + "nd";
}else if( lastStringElement == "3" && n % 100 !== 13 ){
result = nToString + "rd";
}else{
result = nToString + "th";
}


}


return result;
}


console.log(numberToOrdinal(-111));
console.log(numberToOrdinal(0));
console.log(numberToOrdinal(11));
console.log(numberToOrdinal(15));
console.log(numberToOrdinal(21));
console.log(numberToOrdinal(32));
console.log(numberToOrdinal(43));
console.log(numberToOrdinal(70));
console.log(numberToOrdinal(111));
console.log(numberToOrdinal(300));
console.log(numberToOrdinal(101));

输出

false
0
11th
15th
21st
32nd
43rd
70th
111th
300th
101st

这里有一个稍微不同的方法(我不认为其他答案会这样做)。我不确定我是喜欢还是讨厌它,但它确实有效!

export function addDaySuffix(day: number) {
const suffixes =
'  stndrdthththththththththththththththththstndrdthththththththst';
const startIndex = day * 2;


return `${day}${suffixes.substring(startIndex, startIndex + 2)}`;
}

Intl.PluralRules,即标准方法。

我只是想在这里放弃做这个的规范方法,因为似乎没有人知道它。

如果你想让你的代码

  • 自我记录
  • 易于本地化
  • 用现代标准

——这才是正确的方法。

const english_ordinal_rules = new Intl.PluralRules("en", {type: "ordinal"});
const suffixes = {
one: "st",
two: "nd",
few: "rd",
other: "th"
};
function ordinal(number/*: number */) {
const category = english_ordinal_rules.select(number);
const suffix = suffixes[category];
return (number + suffix);
} // -> string


const test = Array(201)
.fill()
.map((_, index) => index - 100)
.map(ordinal)
.join(" ");
console.log(test);


Code-golf

虽然我不推荐高尔夫与你的代码和杀死可读性,我提出了一个高尔夫球手(92字节):

n=>n+{e:"st",o:"nd",w:"rd",h:"th"}[new Intl.PluralRules("en",{type:"ordinal"}).select(n)[2]]

你可以使用Moment库是本地数据函数

代码:

moment.localeData().ordinal(1)
//1st

这是为一个内衬和爱好者的es6

let i= new Date().getDate


// I can be any number, for future sake we'll use 9


const j = I % 10;
const k = I % 100;


i = `${i}${j === 1 &&  k !== 11 ? 'st' : j === 2 && k !== 12 ? 'nd' : j === 3 && k !== 13 ? 'rd' : 'th'}`}


console.log(i) //9th

+be number的另一个选项是:

console.log(["st","nd","rd"][((i+90)%100-10)%10-1]||"th"]

也可以用这些来去掉序数前缀:

console.log(i.parseInt("8th"))


console.log(i.parseFloat("8th"))

请随意修改以适合您的需要

const getOrdinalNum = (n) => n + (n > 0 ? ['th', 'st', 'nd', 'rd'][(n > 3 && n < 21) || n % 10 > 3 ? 0 : n % 10] : '');

我想引用链接中可用的答案

function ordinal(n) {
var s = ["th", "st", "nd", "rd"];
var v = n%100;
return n + (s[(v-20)%10] || s[v] || s[0]);
}