Bir sayıya st, nd, rd ve th (sıra) son ekini ekleyin


161

Geçerli bir güne dayalı olarak dinamik olarak bir metin dizisi oluşturmak istiyorum. Dolayısıyla, örneğin, 1. günse, kodumun = "Onun <dynamic> 1 * <dynamic string> st </ dynamic string> * </dynamic>" olmasını istiyorum.

Toplamda 12 gün var, bu yüzden aşağıdakileri yaptım:

  1. 12 gün boyunca dönen bir for döngüsü kurdum.

  2. HTML'imde, elemanıma onu hedeflemek için benzersiz bir kimlik verdim, aşağıya bakın:

    <h1 id="dynamicTitle" class="CustomFont leftHeading shadow">On The <span></span> <em>of rest of generic text</em></h1>
    
  3. Ardından, for döngümün içinde şu koda sahibim:

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

GÜNCELLEME

Bu, istendiği gibi for döngüsünün tamamıdır:

$(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
Kaynak kodunuz yeterince kısaysa, tüm içeriği yayınlayıp tam olarak neyin yanlış olduğunu veya kafanızı karıştıran şeyin ne olduğunu söyler misiniz?
RonaldBarzell

Kodunuzun şu anda yaptığı / yapmadığı şey nedir? Neyin yanlış gittiğini açıkça belirtmediniz.
Sivri

Sanırım gösterilen kod if, döngü tarafından daha da içerilen bir bloğun içeriği mi? Daha fazla kod göster ....
MrCode

@MrCode - Evet haklısınız. Gönderiyi tüm for döngüsünü içerecek şekilde güncelledim. Umarım bu durumu düzeltir!
Antonio Vasilev

düzgün ve iyi çalışıyor.
Dan Jay

Yanıtlar:


363

Kurallar aşağıdaki gibidir:

  • st, 1 ile biten sayılarla kullanılır (ör. 1., önce telaffuz edilir)
  • nd, 2 ile biten sayılarla kullanılır (ör. 92., doksan saniye olarak telaffuz edilir)
  • rd, 3 ile biten sayılarla kullanılır (örneğin, 33., otuz üçüncü olarak telaffuz edilir)
  • Yukarıdaki kurallara bir istisna olarak, 11, 12 veya 13 ile biten tüm "genç" sayıları -th kullanır (ör. 11., 11., 11., 112., yüz [ve] onikinci olarak okunur)
  • th, diğer tüm sayılar için kullanılır (örn. 9'uncu, dokuzuncu olarak telaffuz edilir).

Aşağıdaki JavaScript kodu (Haziran '14'te yeniden yazılmıştır) bunu başarır:

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 arası sayılar için örnek çıktı:

  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
Benim için de gerçekten iyi çalıştı: dateString = monthNames [newValue.getUTCMonth ()] + "" + numberSuffix (newValue.getUTCDate ()) + "," + newValue.getUTCFullYear ();
Michael J. Calkins

9
Bu, üç "genç" sayı için istisnaları gerektiği gibi ele almaz. Sayı, örneğin için 111, 112ve 113sonuçlanmalıdır "111th", "112th"ve "113th"sırasıyla değil"111st" , "112nd"ve "113rd"şu anda kodlanmış olarak fonksiyonu tarafından üretilen.
martineau

3
Görünüşe göre bu cevap mükemmel bir şekilde gelişti. Tüm katkıda bulunanlara teşekkür ederim.
Lonnie Best

8
Gerçek bir sebep olmadan onu bir ES6 lambda olarak sıkıştırdım: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 yeterince komik, ~ π / 2 yıl sonra hala okuyabiliyorum.
Camilo Martin

217

Gönderen 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))
);


23
Açıklama eklemek, onu daha iyi bir cevap haline getirebilir!
Pugazh

5
@Pugazh A. bul s [v% 10] if> = 20 (20th ... 99th), B. bulamazsanız, s [v] (0th..3rd) deneyin, C. hala bulunamazsa, s kullanın [0] (4..19.)
Sheepy

4
neden çift işlev adına giriyor?
Gisheri

49

Sıralı son ekler için minimum tek satırlık yaklaşım

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

(bu pozitif tam sayılar içindir, diğer varyasyonlar için aşağıya bakın)

Açıklama

Son eklerle bir dizi ile başlayın ["st", "nd", "rd"]. 1, 2, 3 ile biten (ancak 11, 12, 13 ile bitmeyen) tam sayıları 0, 1, 2 dizinlerine eşlemek istiyoruz.

Diğer tam sayılar (11, 12, 13 ile bitenler dahil) başka herhangi bir şeye eşlenebilir - dizide bulunmayan dizinler olarak değerlendirilir undefined. Bu, javascript'te yanlıştır ve mantıksal veya ( || "th") kullanımıyla ifade "th"bu tamsayılar için geri dönecektir , bu tam olarak istediğimiz şeydir.

İfade ((n + 90) % 100 - 10) % 10 - 1eşlemeyi yapar. Parçalamak:

  • (n + 90) % 100: Bu ifade, giriş tamsayısını alır - 10 mod 100, 10'dan 0'a, ... 99'dan 89'a, 0'dan 90'a, ..., 9'dan 99'a. Şimdi 11, 12, 13 ile biten tamsayılar altta end (1, 2, 3 ile eşlendi).
  • - 10: Şimdi 10, -10, 19 - -1, 99 - 79, 0 - 80, ... 9 - 89 ile eşlenir. 11, 12, 13 ile biten tamsayılar negatif tamsayılarla (9, −8, −7).
  • % 10: Şimdi 1, 2 veya 3 ile biten tüm tamsayılar 1, 2, 3 ile eşlenir. Diğer tüm tamsayılar başka bir şeye eşlenir (11, 12, 13 hala -9, -8, -7 ile eşlenir).
  • - 1: Biri çıkarmak 1, 2, 3'ün 0, 1, 2'ye son eşlemesini verir.

Çalıştığını doğrulamak

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>

Varyasyonlar

Negatif tam sayılara izin verilmesi:

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

ES6 şişman ok sözdiziminde (anonim işlev):

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

Güncelleme

Pozitif tamsayılar için daha da kısa bir alternatif, ifadedir

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

Açıklama için bu gönderiye bakın .

Güncelleme 2

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

3
zarif. benim favorim.
guy mograbi


14

Intl.PluralRules, Standart bir yöntem.

Kimse bilmiyor gibi göründüğü için, bunu yapmanın kanonik yolunu burada bırakmak istiyorum.

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
Negatif sayıları ele alan tek cevap bu olduğu için tek iyi genel çözüm budur.
RobG

8

Bir diziye sayıda bölme ve kolayca kullanılarak numarasının son 2 rakamını kontrol edebilir tersine çevrilerek array[0]ve array[1].

Bir sayı gençlerde ise array[1] = 1"th" gerektirir.

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

Bu harika. Teşekkürler!
Jason

11, 12, 13
psx

2
@psx 5. satırdaki koşul bunun içindir.
nick

7

Sadece 12 günün mü var? Bunu sadece basit bir arama dizisi yapmak isterdim:

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

sonra

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

veya

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

Teşekkürler, bu sorunumu çözdü. Son eki günle eşleştiremedim, bu yüzden diziyi hem sayılarla hem de mükemmel çalışan son ekle doldurdum. Sonra onu basitçe şöyle adlandırdım$("#dynamicTitle span").html(suffix[i-1]);
Antonio Vasilev

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

Güzel küçük oneliner, anlaşılması biraz zor
bryc

n - 1Parça nedeniyle n == 0 olduğunda başarısız olur (tanımsız döndürür). 110'dan büyük sayılar için de başarısız olur, örneğin getSuffix(111)"st" döndürür. OP'nin 1'den 12'ye kadar olan sayılardaki problemini çözer, ancak genel bir çözüm değildir. :-(
RobG

3

Bu sorunu çözmek için bu işlevi yazdım:

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

Bununla .addSuffix()herhangi bir sayıya koyabilirsiniz ve istediğiniz şeyle sonuçlanacaktır. Örneğin:

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

Sanırım numberbu dizede var lastDigits=n.substring(number.length-2);değiştirilmelithis
Slava Abakumov

bunun nyerine olmalı this, ancak bu hatayı işaret ettiğiniz için teşekkürler! :)
Jimmery

2

Sıralı işlevin alternatif bir sürümü aşağıdaki gibi olabilir:

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

Değişkenler daha açık bir şekilde adlandırılır, deve durumu kuralını kullanır ve daha hızlı olabilir.


Ancak bu, yerelleştirilmiş kod tabanları için çalışmayacaktır.
Daniel Harvey

1

Bu basit işlevi geçen gün yazdım. Bir tarih için daha büyük sayılara ihtiyacınız olmasa da, bu daha yüksek değerleri de karşılayacaktır (1013., 36021. Vb.)

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

Ek açıklamalı sürüme https://gist.github.com/furf/986113#file-annotated-js adresinde bakın

Kısa, tatlı ve verimli, tıpkı yardımcı program işlevlerinin olması gerektiği gibi. Herhangi bir işaretli / işaretsiz tamsayı / kayan nokta ile çalışır. (Şamandıraları sıralı hale getirme ihtiyacını hayal edemememe rağmen)


0

İşte başka bir seçenek.

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

Gençler için istisnayı fark ettiniz mi? Gençler çok kibar!

Düzenleme: 11. ve 12.'yi unuttum


0

Mevcut cevabı tamamlamak için bu soruya işlevsel bir cevap vermek istedim:

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)

özel değerlerden oluşan bir dizi oluşturduk, hatırlanması gereken önemli şey dizilerin sıfır tabanlı bir indeksine sahip olmasıdır, bu nedenle ordinalSuffix [0] 'st'ye eşittir.

NumberToOrdinal fonksiyonumuz, sayının genç bir sayı ile bitip bitmediğini kontrol eder, bu durumda sayıyı 'th' ile ekler, çünkü tüm sayılar 'th' olur. Sayının bir genç olmaması durumunda, sayıyı, eksi 1 sayısının (sıfır tabanlı bir indeks kullandığımız için) mod 10'un kalan 2'ye sahip olup olmadığı ile belirlenen sayıyı sıraya ekleyen addSuffix'e iletiriz. veya daha az diziden alınır, aksi takdirde "th" dir.

örnek çıktı:

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

Eşyalarım için yaptığım eskisi ...

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

Yukarıdaki kod hakkında bir açıklama ekleyin. Bir kod parçasından çok daha fazlasına yardımcı olur.
Mathews Sunny


0

Bu işlevi daha yüksek sayılar ve tüm test durumları için yazdı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

İşte biraz farklı bir yaklaşım (diğer cevapların bunu yaptığını sanmıyorum). Seviyor muyum yoksa ondan nefret mi ediyorum emin değilim ama işe yarıyor!

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

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

-1

Bunu şiddetle tavsiye ediyorum, okuması çok kolay ve anlaşılır. Umarım yardımcı olur?

  • Negatif tamsayı, yani 1'den küçük sayı kullanımından kaçınır ve yanlış döndürür
  • Giriş 0 ise 0 döndürür
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));

ÇIKTI

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

-1

Bu bir gömlek ve es6 sevenler içindir

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 için başka bir seçenek şudur:

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

Sıralı önekten kurtulmak için sadece şunları kullanın:

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

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

İhtiyacınız olana uyacak şekilde değiştirmekten çekinmeyin


-7

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

Kullanabilirsiniz

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

son eki konumlandırmak için


4
OP'nin istediği bu değil
TetraDev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.