Thêm hậu tố st, nd, nd và th (thứ tự) vào một số


150

Tôi muốn tự động tạo một chuỗi văn bản dựa trên một ngày hiện tại. Vì vậy, ví dụ, nếu đó là ngày 1 thì tôi muốn mã của mình tạo = "Đó là <động> 1 * <chuỗi động> st </ chuỗi động> * </ động>".

Tổng cộng có 12 ngày nên tôi đã làm như sau:

  1. Tôi đã thiết lập một vòng lặp for trong vòng 12 ngày.

  2. Trong html của tôi, tôi đã cung cấp cho phần tử của mình một id duy nhất để nhắm mục tiêu, xem bên dưới:

    <h1 id="dynamicTitle" class="CustomFont leftHeading shadow">On The <span></span> <em>of rest of generic text</em></h1>
  3. Sau đó, trong vòng lặp for của tôi, tôi có đoạn mã sau:

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

CẬP NHẬT

Đây là toàn bộ vòng lặp theo yêu cầu:

$(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
Nếu mã nguồn của bạn đủ ngắn, bạn có phiền khi đăng toàn bộ nội dung không, và cũng nói chính xác điều gì sai hoặc điều gì làm bạn bối rối?
RonaldBarzell

Mã của bạn hiện không / không làm gì? Bạn đã không nói rõ những gì đang xảy ra.
Mũi nhọn

Tôi đoán mã được hiển thị là nội dung của một ifkhối được chứa thêm bởi vòng lặp? Hiển thị thêm mã ....
MrCode

@MrCode - Có bạn đúng. Tôi đã cập nhật bài viết để bao gồm toàn bộ vòng lặp for. Tôi hy vọng điều này sẽ xóa nó!
Antonio Vasilev

gọn gàng và nó hoạt động tốt.
Dan Jay

Câu trả lời:


343

Các quy tắc như sau:

  • st được sử dụng với các số kết thúc bằng 1 (ví dụ 1, phát âm trước)
  • nd được sử dụng với các số kết thúc bằng 2 (ví dụ 92, phát âm là chín mươi giây)
  • Số được sử dụng với các số kết thúc bằng 3 (ví dụ 33, phát âm ba mươi ba)
  • Như một ngoại lệ đối với các quy tắc trên, tất cả các số "thiếu niên" kết thúc bằng 11, 12 hoặc 13 sử dụng -th (ví dụ: thứ 11, phát âm thứ mười một, 112, phát âm một trăm [và] thứ mười hai)
  • th được sử dụng cho tất cả các số khác (ví dụ 9, phát âm thứ chín).

Mã JavaScript sau (được viết lại vào ngày 14 tháng 6) thực hiện điều này:

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

Đầu ra mẫu cho các số từ 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
Nó cũng hoạt động rất tốt cho tôi
Michael J. Calkins

9
Điều này không xử lý các trường hợp ngoại lệ cho ba số "tuổi teen" đúng cách. Ví dụ những con số 111, 112113nên kết quả trong "111th", "112th""113th"tương ứng, không những "111st", "112nd""113rd"được sản xuất bởi các chức năng như hiện mã hóa.
martineau

3
Câu trả lời này dường như đã phát triển hoàn hảo. Cảm ơn tất cả những người đóng góp.
Lonnie hay nhất

7
Tôi đã quảng cáo nó như một lambda ES6 mà không có lý do thực sự: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
@Anomaly đủ vui, sau ~ π / 2 năm sau tôi vẫn có thể đọc nó.
Camilo Martin

210

Từ 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
Thêm lời giải thích có thể làm cho nó một câu trả lời tốt hơn!
Pugazh

5
@Pugazh A. tìm s [v% 10] if> = 20 (20 ... 99th), B. nếu không tìm thấy, hãy thử s [v] (0th..3rd), C. nếu vẫn không tìm thấy, hãy sử dụng s [0] (4th..19th)
Sheepy

4
Tại sao đôi có được trong tên chức năng mặc dù?
Gisheri

46

Cách tiếp cận một dòng tối thiểu cho hậu tố thứ tự

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

(đây là số nguyên dương, xem bên dưới để biết các biến thể khác)

Giải trình

Bắt đầu với một mảng với các hậu tố ["st", "nd", "rd"]. Chúng tôi muốn ánh xạ các số nguyên kết thúc bằng 1, 2, 3 (nhưng không kết thúc vào 11, 12, 13) cho các chỉ số 0, 1, 2.

Các số nguyên khác (bao gồm cả các số nguyên kết thúc vào 11, 12, 13) có thể được ánh xạ tới bất kỳ thứ gì khác mà các chỉ số không tìm thấy trong mảng sẽ đánh giá undefined. Đây là giả mạo trong javascript và với việc sử dụng logic hoặc ( || "th"), biểu thức sẽ trả về "th"các số nguyên này, đó chính xác là những gì chúng ta muốn.

Biểu thức ((n + 90) % 100 - 10) % 10 - 1thực hiện ánh xạ. Phá vỡ nó:

  • (n + 90) % 100: Biểu thức này lấy số nguyên đầu vào - 10 mod 100, ánh xạ 10 đến 0, ... 99 đến 89, 0 đến 90, ..., 9 đến 99. Bây giờ các số nguyên kết thúc ở 11, 12, 13 ở mức thấp hơn kết thúc (ánh xạ đến 1, 2, 3).
  • - 10: Bây giờ 10 được ánh xạ tới −10, 19 đến −1, 99 đến 79, 0 đến 80, ... 9 đến 89. Các số nguyên kết thúc ở 11, 12, 13 được ánh xạ tới các số nguyên âm (−9, −8, −7).
  • % 10: Bây giờ tất cả các số nguyên kết thúc bằng 1, 2 hoặc 3 được ánh xạ thành 1, 2, 3. Tất cả các số nguyên khác được ánh xạ tới một thứ khác (11, 12, 13 vẫn được ánh xạ tới −9, −8, 7).
  • - 1: Trừ đi một cho ánh xạ cuối cùng của 1, 2, 3 thành 0, 1, 2.

Xác minh rằng nó hoạt động

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>

Biến thể

Cho phép số nguyên âm:

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

Trong cú pháp mũi tên chất béo ES6 (hàm ẩn danh):

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

Cập nhật

Một thay thế thậm chí ngắn hơn cho số nguyên dương là biểu thức

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

Xem bài này để giải thích.

Cập nhật 2

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

3
thanh lịch. yêu thích của tôi
anh chàng mograbi


10

Intl.PluralRules, phương pháp chuẩn .

Tôi chỉ muốn bỏ cách thức kinh điển để làm điều này ở đây, vì dường như không ai biết điều đó.

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
Đây là giải pháp chung tốt duy nhất vì đây là câu trả lời duy nhất ở đây xử lý các số âm.
RobG

7

Bạn chỉ có 12 ngày? Tôi muốn thử làm cho nó chỉ là một mảng tra cứu đơn giản:

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

sau đó

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

hoặc là

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

Cảm ơn, điều này đã giải quyết vấn đề của tôi. Tôi không thể có được hậu tố phù hợp với ngày vì vậy tôi chỉ điền vào mảng với cả hai số và hậu tố hoạt động hoàn hảo. Sau đó, tôi chỉ đơn giản gọi nó như thế$("#dynamicTitle span").html(suffix[i-1]);
Antonio Vasilev

7

Bằng cách chia số thành một mảng và đảo ngược, chúng ta có thể dễ dàng kiểm tra 2 chữ số cuối của số bằng cách sử dụng array[0]array[1] .

Nếu một số ở tuổi thiếu niên, array[1] = 1nó yêu cầu "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";
}

Đây là hoàn hảo. Cảm ơn!
Jason

Bạn phải loại trừ 11, 12, 13
psx

2
@psx Đó là điều kiện trên dòng 5 dành cho.
nick

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

Oneliner nhỏ xinh, hơi khó hiểu
bryc

Thất bại trong đó n == 0 do n - 1một phần (trả về không xác định). Cũng không thành công cho các số lớn hơn 110, ví dụ getSuffix(111)trả về "st". Nó giải quyết vấn đề của OP trong đó các số từ 1 đến 12, nhưng không phải là một giải pháp chung. :-(
RobG

2

Tôi đã viết chức năng này để giải quyết vấn đề này:

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

Với điều này, bạn có thể chỉ cần đặt .addSuffix()vào bất kỳ số nào và nó sẽ dẫn đến những gì bạn muốn. Ví dụ:

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

Tôi nghĩ numbertrong chuỗi này var lastDigits=n.substring(number.length-2);nên được đổi thànhthis
Slava Abakumov

nó nên được nthay thế this, nhưng cảm ơn vì đã chỉ ra lỗi đó! :)
Jimmery

2

Một phiên bản thay thế của chức năng thứ tự có thể như sau:

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

Các biến được đặt tên rõ ràng hơn, sử dụng quy ước trường hợp lạc đà và có thể nhanh hơn.


Điều này sẽ không làm việc cho các cơ sở mã địa phương tuy nhiên.
Daniel Harvey

1

Tôi đã viết chức năng đơn giản này vào ngày khác. Mặc dù cho một ngày bạn không cần số lớn hơn, điều này cũng sẽ phục vụ cho các giá trị cao hơn (1013th, 36021, v.v.)

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

Xem phiên bản chú thích tại https://gist.github.com/furf/986113#file-annotated-js

Ngắn gọn, ngọt ngào và hiệu quả, giống như các chức năng tiện ích nên có. Hoạt động với bất kỳ số nguyên / dấu không dấu / dấu. (Mặc dù tôi không thể tưởng tượng được cần phải phong chức phao)


0

Đây là một lựa chọn khác.

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

Chú ý ngoại lệ cho thanh thiếu niên? Thanh thiếu niên rất akward!

Chỉnh sửa: Quên khoảng 11 và 12


0

Tôi muốn cung cấp một câu trả lời chức năng cho câu hỏi này để bổ sung cho câu trả lời hiện có:

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)

chúng tôi đã tạo ra một mảng các giá trị đặc biệt, điều quan trọng cần nhớ là các mảng có chỉ số dựa trên số 0 nên ordinalSuffix [0] bằng với 'st'.

Hàm số của chúng tôiToOrdinal kiểm tra xem số có kết thúc bằng số thiếu niên hay không, trong trường hợp đó nối thêm số với 'th' vì tất cả các số thứ tự sau đó là 'th'. Trong trường hợp số đó không phải là thiếu niên, chúng tôi chuyển số cho addSuffix, số này sẽ thêm số vào số thứ tự được xác định nếu số trừ 1 (vì chúng tôi đang sử dụng chỉ số dựa trên số 0) mod 10 có phần còn lại là 2 hoặc ít hơn nó được lấy từ mảng, nếu không nó là 'th'.

đầu ra mẫu:

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

Cái cũ tôi làm cho những thứ của tôi ...

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

Thêm một số mô tả về mã trên. Nó sẽ giúp nhiều hơn một đoạn mã.
Mathews Nắng


0

Tôi đã viết hàm này cho số cao hơn và tất cả các trường hợp thử nghiệm

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

Đây là một cách tiếp cận hơi khác (tôi không nghĩ các câu trả lời khác làm điều này). Tôi không chắc là tôi yêu hay ghét nó, nhưng nó hoạt động!

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

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

0

Điều này là dành cho một liners và những người yêu thích 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

Một tùy chọn khác cho + be number sẽ là:

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

Ngoài ra để thoát khỏi tiền tố thứ tự, chỉ cần sử dụng những điều sau đây:

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

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

cảm thấy tự do để sửa đổi cho phù hợp với bạn cần


0

Bạn cũng có thể sử dụng scales::ordinal()chức năng. Thật nhanh chóng và đơn giản để sử dụng.

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

-1

Tôi thực sự khuyên bạn nên điều này, nó siêu dễ và dễ đọc. Tôi hy vọng nó sẽ giúp?

  • Nó tránh sử dụng số nguyên âm tức là số nhỏ hơn 1 và trả về false
  • Nó trả về 0 nếu đầu vào là 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));

ĐẦU RA

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

-7

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

Bạn có thể dùng

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

để định vị hậu tố


4
Đây không phải là những gì OP yêu cầu
TetraDev
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.