[removed] Ordinal suffix for numbers with specific CSS class

前端 未结 8 1373
时光说笑
时光说笑 2021-02-14 03:01

I am trying to display numbers within a particular table with ordinal suffixes. The table always shows three numbers which come from an XML file. The numbers show ranks, so for

相关标签:
8条回答
  • 2021-02-14 03:11

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

    See annotated version at https://gist.github.com/furf/986113#file-annotated-js

    Short, sweet, and efficient, just like utility functions should be. Works with any signed/unsigned integer/float. (Even though I can't imagine a need to ordinalize floats)

    0 讨论(0)
  • 2021-02-14 03:12

    Ordinal suffix in one line

    var integerWithSuffix=originalInteger+(['st','nd','rd'][( originalInteger +'').match(/1?\d\b/)-1]||'th');
    

    the concatenation of the original number and a string representing the ordinal derived from an array indexed by the result of a regex search on that number

    http://jsfiddle.net/thisishardcoded/DbSMB/

    0 讨论(0)
  • 2021-02-14 03:14

    My own suggestion, would be:

    $(".ordinal").text(function (i, t) {
        i++;
        var str = i.toString().slice(-1),
            ord = '';
        switch (str) {
            case '1':
                ord = 'st';
                break;
            case '2':
                ord = 'nd';
                break;
            case '3':
                ord = 'rd';
                break;
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case '0':
                ord = 'th';
                break;
        }
        return i + ord;
    });
    

    JS Fiddle demo.

    This effectively takes the incremented number (i++, in order to start from 1 not 0), converts it to a string, then looks at the last number of that string. This should work for any number, since the ordinal is based purely on that last number.

    You could also extend the Number prototype to implement this functionality:

    Number.prototype.ordinate = function(){
        var num = this + 1,
            last = num.toString().slice(-1),
            ord = '';
        switch (last) {
            case '1':
                ord = 'st';
                break;
            case '2':
                ord = 'nd';
                break;
            case '3':
                ord = 'rd';
                break;
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case '0':
                ord = 'th';
                break;
        }
        return num.toString() + ord;
    };
    
    $(".ordinal").text(function (i, t) {
        return i.ordinate();
    });
    

    JS Fiddle demo.

    Edited to offer a slight alternative:

    Number.prototype.ordinate = function(){
        var num = this,
            last = num.toString().slice(-1),
            ord = '';
        switch (last) {
            case '1':
                ord = 'st';
                break;
            case '2':
                ord = 'nd';
                break;
            case '3':
                ord = 'rd';
                break;
            default:
                ord = 'th';
                break;
        }
        return num.toString() + ord;
    };
    
    $(".ordinal").text(function (i,t) {
        return t.replace(/(\d+)/g, function(a){
            return parseInt(a, 10).ordinate();
        });
    });
    

    JS Fiddle demo.

    This essentially iterates over each .ordinal element, replacing the numbers present with the (same) numbers with the ordinal suffix added to it.


    Edited to address the problem, raised in the comments, below, that 11, 12 and 13 were receiving the ordinal suffix of st, nd and rd (respectively). This is now corrected to being th in all cases:

    Number.prototype.ordinate = function(){
        var num = this,
            numStr = num.toString(),
            last = numStr.slice(-1),
            len = numStr.length,
            ord = '';
        switch (last) {
            case '1':
                ord = numStr.slice(-2) === '11' ? 'th' : 'st';
                break;
            case '2':
                ord = numStr.slice(-2) === '12' ? 'th' : 'nd';
                break;
            case '3':
                ord = numStr.slice(-2) === '13' ? 'th' : 'rd';
                break;
            default:
                ord = 'th';
                break;
        }
        return num.toString() + ord;
    };
    

    JS Fiddle demo.

    References:

    • slice().
    • switch().
    • text().
    • toString().
    0 讨论(0)
  • 2021-02-14 03:14

    I would do something like this, based on David Thomas's answer:

    Number.prototype.ordinate = function(){
        var num = this,
            ones = num % 10, //gets the last digit
            tens = num % 100, //gets the last two digits
            ord = ["st","nd","rd"][ tens > 10 && tens < 20 ? null : ones-1 ] || 'th';
        return num.toString() + ord;
    };
    

    It accomplishes the same thing. If a number's last 2 digits are within the 11-19 range OR the last digit is between 4-0 it defaults to 'th', otherwise it will pull a 'st', 'nd' or 'rd' out of the array based on the ones place.

    I like the idea of creating a prototype function very much but I would definitely leave the incrementation of the index outside of the prototype function to make it more versatile:

    $(".ordinal").text(function (i, t) {
        return (++i).ordinate();
    });
    

    JS Fiddle Demo

    0 讨论(0)
  • 2021-02-14 03:18
    function nth(n){
        if(isNaN(n) || n%1) return n;   
        var s= n%100;
        if(s>3 && s<21) return n+'th';
        switch(s%10){
            case 1: return n+'st';
            case 2: return n+'nd';
            case 3: return n+'rd';
            default: return n+'th';
        }
    }
    

    You can take care of the teens in their own line, other integers follow the last digit rules.

    0 讨论(0)
  • 2021-02-14 03:27

    I created two approaches one using Prototype, the other as a plugin :

    Number.prototype.between = function(n,m){ return this > n && this < m }
    Number.prototype.ORDINATE_INDEX = ["th","st","nd","rd"];
    Number.prototype.toOrdinate = function(){
        var
            nthMod = (this % 10),
            index =  nthMod > 3 || this.between(10,20) ? 0 : nthMod
        ;
    
        return this + this.ORDINATE_INDEX[index];
    };
    
    $(".ordinal").text(function (index, element) {
        return parseInt(element).toOrdinate();
    });
    

    This is the one as a Jquery Plugin :

    (function($){
        var numberTool = new (function(){
            var private = {};
    
            private.ORDINATE_INDEX = ["th","st","nd","rd"];
    
            private.parseOrdinary = function(number)
            {
                var
                    nthMod = (number % 10),
                    index =  nthMod > 3 || private.between(number, 10,20) ? 0 : nthMod
                ;
    
                return number + private.ORDINATE_INDEX[index];
            }
    
            private.between = function(number, n,m){
                return number > n && number < m
            }
    
            this.isNumeric = function(number)
            {
                return !isNaN(parseFloat(number)) && isFinite(number);
            }
    
            this.toOrdinary = function(number)
            {
                return this.isNumeric(number) ? private.parseOrdinary(number) : number;
            }
        });
    
    
        $.fn.toOrdinary = function(){
            return this.each(function(){
                $element = $(this);
                $element.text(numberTool.toOrdinary($element.text()));
            }); 
        };
    })(jQuery);
    
    $(".ordinal").toOrdinary();
    $(".ordinal").toOrdinary();
    $(".ordinal").toOrdinary();
    

    Tested on JSFIDDLE:

    The prototype version example : http://jsfiddle.net/f8vQr/6/

    The JQuery version example : http://jsfiddle.net/wCdKX/27/

    0 讨论(0)
提交回复
热议问题