将st,nd,rd和th(普通)后缀添加到数字


150

我想根据当前日期动态生成文本字符串。因此,例如,如果是第一天,那么我希望我的代码生成=“ Its <dynamic> 1 * <dynamic string> st </ 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. 然后,在我的for循环中,我有以下代码:

    $("#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"
    }

更新

这是请求的整个for循环:

$(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) {
            }
        }
    }

1
如果您的源代码足够简短,您是否愿意发布完整的内容,并确切地说出什么地方错了或让您感到困惑?
罗纳德·巴泽尔(RonaldBarzell)2012年

您的代码当前不执行/不执行什么操作?您没有明确说明出了什么问题。
Pointy 2012年

我猜显示的代码是if循环的进一步包含的块的内容吗?显示更多代码....
MrCode 2012年

@MrCode-是的,您是正确的。我已经更新了帖子,以包括整个for循环。我希望这可以清除它!
Antonio Vasilev 2012年

整洁,效果很好。
丹·杰伊

Answers:


345

规则如下:

  • st与以1结尾的数字(例如1st,首先发音)一起使用
  • nd与以2结尾的数字一起使用(例如,第92个,发音为90秒)
  • rd与以3结尾的数字一起使用(例如33rd,发音为三十三)
  • 作为上述规则的例外,所有以11、12或13结尾的“青少年”数字都使用-th(例如,第11个,发音为第11个,第112个,发音为第100个和第十二个)
  • th用于所有其他数字(例如,第9个,发音为第9个)。

以下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

1
它对我来说也非常有效:dateString = monthNames [newValue.getUTCMonth()] +“” + numberSuffix(newValue.getUTCDate())+“,” + newValue.getUTCFullYear();
Michael J. Calkins 2013年

9
这不能正确处理三个“青少年”数字的异常。例如,数字111112113应导致"111th""112th""113th"分别"111st""112nd",和"113rd"通过作为当前编码的函数产生的。
martineau 2014年

3
这个答案似乎已经完美地发展了。谢谢所有贡献者。
Lonnie Best

7
我无缘无故将它压缩为ES6 lambda:n=>n+(n%10==1&&n%100!=11?'st':n%10==2&&n%100!=12?'nd':n%10==3&&n%100!=13?'rd':'th')
Camilo Martin

1
@异常有趣,在〜π/ 2年后,我仍然可以阅读它。
卡米洛·马丁

210

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))
);


22
添加说明可以使其成为一个更好的答案!
Pugazh

5
@Pugazh A.如果> = 20(20th ... 99th),则找到s [v%10] 99th),则如果未找到,请尝试s [v](0th..3rd),C。如果仍然找不到,请使用s [0](4th..19th)
Sheepy

4
为什么双倍输入函数名称呢?
Gisheri

46

序数后缀的最小单行方法

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、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>

变化

允许负整数:

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

在ES6中,胖箭头语法(匿名函数):

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

更新资料

正整数的更短替代形式是表达式

[,'st','nd','rd'][n%100>>3^1&&n%10]||'th'

看到这个帖子以获取解释。

更新2

[,'st','nd','rd'][n/10%10^1&&n%10]||'th'

3
优雅。我的最爱。
guy mograbi


10

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) {
	const suffix = suffixes[english_ordinal_rules.select(number)];
	return (number + suffix);
}

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


1
这是唯一好的通用解决方案,因为这是处理负数的唯一答案。
RobG

7

你只有十二天?我很想使其成为一个简单的查找数组:

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'

谢谢,这解决了我的问题。我无法获得与当天匹配的后缀,所以我只在数组中填充了数字和后缀,它们都可以正常工作。然后我就这样简单地称它为$("#dynamicTitle span").html(suffix[i-1]);
Antonio Vasilev 2012年

7

通过将数字分成一个数组并取反,我们可以轻松地使用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 in the teens
        switch (array[0]) {
            case "1": return "st";
            case "2": return "nd";
            case "3": return "rd";
        }
    }

    return "th";
}

太棒了。谢谢!
杰森

您必须排除11,12、13
psx

2
@psx这就是第5行的条件。
尼克

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

不错的小oneliner,有点难以理解
bryc

n - 1部分而失败,其中n == 0 (返回未定义)。对于大于110的数字也失败,例如getSuffix(111)返回“ st”。它确实解决了OP的数字为1到12的问题,但这不是一般的解决方案。:-(
RobG

2

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

// 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

我认为number该字符串var lastDigits=n.substring(number.length-2);应更改为this
Slava Abakumov

应该是,n而不是this,但是感谢您指出该错误!:)
Jimmery

2

序数函数的替代版本如下:

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";
}

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


但是,这不适用于本地化的代码库。
丹尼尔·哈维

1

前几天我写了这个简单的函数。尽管对于日期而言,您不需要较大的数字,但这也可以满足较高的值(第1013、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;
};

1

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上查看带注释的版本

就像实用程序功能一样,它简短,甜蜜且高效。适用于任何有符号/无符号整数/浮点数。(即使我无法想象需要整理浮点数)


0

这是另一个选择。

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


0

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

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”。如果数字不是青少年,我们将数字传递给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

0

我为我的东西做的旧的...

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;
     }
}

添加有关上述代码的一些描述。这将不仅仅是一段代码。
Mathews Sunny Sunny

0

强烈推荐出色的date-fns库。快速,模块化,不变,可与标准日期配合使用。

import * as DateFns from 'date-fns';

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

请参阅date-fns文档:https ://date-fns.org/v2.0.0-alpha.9/docs/format


0

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

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')
    }
}

0

这是一种略有不同的方法(我认为其他答案没有做到这一点)。我不确定是爱还是恨它,但是它有效!

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

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

0

这是给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"))

随时进行修改以适合您的需求


0

您也可以使用该scales::ordinal()功能。它快速且易于使用。

scales::ordinal(1:12)
## [1] "1st"  "2nd"  "3rd"  "4th"  "5th"  "6th"  "7th"  "8th"  "9th"  "10th" "11th" "12th"

-1

我强烈建议这样做,它非常容易阅读。希望对您有帮助吗?

  • 它避免使用负整数,即小于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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.