12

是否有 JavaScript 代码片段可以取值 1-31 并将其转换为第 1、第 2、第 3 等?

谢谢!

4

4 回答 4

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

测试

getOrdinal("test");   // test
getOrdinal(1.5);      // 1.5
getOrdinal(1);        // 1st
getOrdinal(2);        // 2nd
getOrdinal(3);        // 3rd
getOrdinal(4);        // 4th
getOrdinal(true);     // true
getOrdinal(Infinity); // Infinity
getOrdinal(NaN);      // NaN
getOrdinal(void 0);   // undefined
于 2012-09-19T01:40:05.263 回答
3

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

Number.prototype.toOrdinal = function() {
  var n = this.valueOf(),
      s = [ 'th', 'st', 'nd', 'rd' ],
      v = n % 100;
  return n + (s[(v-20)%10] || s[v] || s[0])
}

示例使用:

var someDay = Math.floor(Math.random() * 31 + 1);
alert(someDay.toOrdinal())

或者你可能认为猴子补丁是邪恶的;像往常一样,YMMV。

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

添加逻辑说明。特定于 Javascript 的关键点:

  1. %运算符返回负除数模正除数的负结果(所以是-1 % 5-1模运算符的许多其他实现只返回和之间的答案0n-1所以-1 % 54)。
  2. 尝试通过超出有效索引范围(负数或超出数组末尾)的值对数组进行索引会导致该undefined值是错误的。

逻辑利用这些事实从包含这些部分的紧凑表达式中返回正确的后缀。

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

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

  3. 如果上述结果均未定义,则返回s[0],即“th”。

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

于 2012-09-19T02:25:34.187 回答
1

Pradeep 的回答很酷,但是如果它不是添加序数的合适值(比如只返回值),那么更强大的东西应该测试该值并做一些明智的事情,例如

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
于 2012-09-19T03:59:48.390 回答
0
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'

https://www.npmjs.com/package/ordinal

于 2015-12-31T22:23:21.027 回答