取一个值1-31并将其转换为序号日期w/JavaScript

取一个值1-31并将其转换为序号日期w/JavaScript,javascript,date,web,frontend,Javascript,Date,Web,Frontend,是否有一个JavaScript代码段将值1-31转换为1、2、3等 谢谢 function getOrdinal(n) { var s=["th","st","nd","rd"], v=n%100; return n+(s[(v-20)%10]||s[v]||s[0]); } 谢谢@RobG 位修改版本 function getOrdinal(n) { if((parseFloat(n) == parseInt(n)) && !isNaN(n))

是否有一个JavaScript代码段将值1-31转换为1、2、3等

谢谢

function getOrdinal(n) {
    var s=["th","st","nd","rd"],
    v=n%100;
    return n+(s[(v-20)%10]||s[v]||s[0]);
}
谢谢@RobG 位修改版本

function getOrdinal(n) {
    if((parseFloat(n) == parseInt(n)) && !isNaN(n)){
        var s=["th","st","nd","rd"],
        v=n%100;
        return n+(s[(v-20)%10]||s[v]||s[0]);
    }
    return n;     
}
测验


您可能会发现将函数修补到数字原型中很方便,因此可以将其作为数字上的方法调用(实现不知羞耻地从Pradeep的答案中窃取):

示例用法:

var someDay = Math.floor(Math.random() * 31 + 1);
alert(someDay.toOrdinal())
或者你可能认为猴子打补丁是邪恶的;像往常一样,YMMV

(我有时会调用这个特殊的方法
th
,但在调用时不需要括号的语言中效果会更好。)

添加对逻辑的解释。特定于Javascript的关键点:

  • %
    运算符返回负除数模正除数的负结果(因此
    -1%5
    -1
    ;模运算符的许多其他实现只返回
    0
    n-1
    之间的答案,因此
    -1%5
    4
  • 如果试图用超出有效索引范围的值(负值或超过数组末尾)对数组进行索引,则会导致
    未定义的值,这是错误的
  • 逻辑利用这些事实从包含这些部分的紧凑表达式返回正确的后缀

  • 尝试访问
    s[(v-20)%10]
    。如果
    v
    (以100为模的给定数字)小于20,则索引为负数,数组访问返回
    未定义的
    。否则,数组索引介于0和9之间。值0到3返回正确的相关后缀(“th”、“st”、“nd”和“rd”),而大于3的值将再次返回未定义的

  • 如果1的结果是定义的值,则返回该值;否则,请尝试访问
    s[v]
    。如果
    v
    本身是0、1、2或3,我们再次分别得到“th”、“st”、“nd”或“rd”。否则,我们将得到一个未定义的值,表达式将转到下一个选项

  • 如果上述两个结果均未定义,则返回
    s[0]
    ,即“th”


  • 结果是,从4到20的所有数字(包括11、12和13)都会得到一个“th”,而以1、2或3结尾的所有其他数字分别得到“st”、“nd”和“rd”。

    Pradeep的答案很酷,但如果不是添加序号的合适值,则应该使用更健壮的方法测试该值并采取明智的措施(比如只返回值),例如

    可在浏览器和节点中工作。然后:

    var ordinal = require('ordinal')
    
    ordinal(1);   //=> '1st'
    ordinal(2);   //=> '2nd'
    ordinal(3);   //=> '3rd'
    ordinal(4);   //=> '4th'
    
    ordinal(11);  //=> '11th'
    ordinal(12);  //=> '12th'
    ordinal(13);  //=> '13th'
    
    ordinal(21);  //=> '21st'
    ordinal(22);  //=> '22nd'
    ordinal(23);  //=> '23rd'
    ordinal(24);  //=> '24th'
    

    哇,我是不是误入了代码高尔夫?:)也返回1.5udnefinedthNaNthtruethfalse,这可能很奇怪,但似乎没什么用处。该函数可能应该测试输入是否是数字或合适的字符串(确保它是整数就足够了)。如果是,则返回数字加序号。否则,返回原始值。添加到
    Number.prototype
    有一个好处,即只应在实际为数字的值上调用它。但它应该测试该值是否为整数,否则不要添加序号(并返回原始值?)。我有一个快速的问题,为什么
    v-20
    ,而不仅仅是v?我从@PradeepSanjaya的答案中复制了这一点,但它是为了处理以1、2和3结尾的数字得到“st”、“nd”和“rd”这一事实-除以11、12和13结尾的数字外,其他数字均为“th”。
    var someDay = Math.floor(Math.random() * 31 + 1);
    alert(someDay.toOrdinal())
    
    var getOrdinal = (function() {
    
        var re = /^\d+$/;
        var ordinal = ["th","st","nd","rd"];
    
        return function (value) {
    
          var t;
    
          if (re.test(String(value))) {
            t = value % 100;
            return t + (ordinal[(t - 20 % 10)] || ordinal[t] || 'th');            
          }
    
          return value;
        }
    }());
    
    getOrdinal( void 0 );  // undefined
    getOrdinal(        );  // undefined
    getOrdinal( NaN    );  // NaN
    getOrdinal( true   );  // true
    getOrdinal( 1.0    );  // 1st
    getOrdinal( ''     );  // '' (empty string)
    getOrdinal(Infinity);  // Infinity
    
    npm install ordinal
    
    var ordinal = require('ordinal')
    
    ordinal(1);   //=> '1st'
    ordinal(2);   //=> '2nd'
    ordinal(3);   //=> '3rd'
    ordinal(4);   //=> '4th'
    
    ordinal(11);  //=> '11th'
    ordinal(12);  //=> '12th'
    ordinal(13);  //=> '13th'
    
    ordinal(21);  //=> '21st'
    ordinal(22);  //=> '22nd'
    ordinal(23);  //=> '23rd'
    ordinal(24);  //=> '24th'