Fügen Sie einer Zahl das Suffix st, nd, rd und th (Ordnungszahl) hinzu


149

Ich möchte dynamisch eine Textzeichenfolge basierend auf einem aktuellen Tag generieren. Wenn es beispielsweise Tag 1 ist, möchte ich, dass mein Code = "Es ist die <dynamische> 1 * <dynamische Zeichenfolge> st </ dynamische Zeichenfolge> * </ dynamische>" generiert .

Es gibt insgesamt 12 Tage, also habe ich Folgendes getan:

  1. Ich habe eine for-Schleife eingerichtet, die die 12 Tage durchläuft.

  2. In meinem HTML-Code habe ich meinem Element eine eindeutige ID gegeben, mit der es als Ziel ausgewählt werden soll (siehe unten):

    <h1 id="dynamicTitle" class="CustomFont leftHeading shadow">On The <span></span> <em>of rest of generic text</em></h1>
  3. Dann habe ich in meiner for-Schleife den folgenden Code:

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

AKTUALISIEREN

Dies ist die gesamte for-Schleife wie gewünscht:

$(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
Wenn Ihr Quellcode kurz genug ist, würde es Ihnen etwas ausmachen, das Ganze zu veröffentlichen und auch genau zu sagen, was falsch ist oder was Sie verwirrt?
RonaldBarzell

Was macht / tut Ihr Code derzeit nicht? Sie haben nicht klar angegeben, was falsch läuft.
Pointy

Ich vermute, der angezeigte Code ist der Inhalt eines ifBlocks, der weiter in der Schleife enthalten ist. Mehr Code
anzeigen

@ MrCode - Ja, Sie sind korrekt. Ich habe den Beitrag so aktualisiert, dass er die gesamte for-Schleife enthält. Ich hoffe das klärt es auf!
Antonio Vasilev

ordentlich und es funktioniert gut.
Dan Jay

Antworten:


343

Die Regeln lauten wie folgt:

  • st wird mit Zahlen verwendet, die mit 1 enden (z. B. 1., zuerst ausgesprochen)
  • nd wird mit Zahlen verwendet, die mit 2 enden (z. B. 92., ausgesprochen neunzig)
  • rd wird mit Zahlen verwendet, die mit 3 enden (z. B. 33., ausgesprochen dreiunddreißig).
  • Als Ausnahme von den obigen Regeln verwenden alle "Teen" -Zahlen, die mit 11, 12 oder 13 enden, -th (z. B. 11., ausgesprochen elfter, 112., ausgesprochen einhundertzwölftes)
  • th wird für alle anderen Zahlen verwendet (zB 9., ausgesprochen 9.).

Der folgende JavaScript-Code (neu geschrieben im Juni '14) erreicht dies:

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

Beispielausgabe für Zahlen zwischen 0 und 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
Es hat auch bei mir sehr gut funktioniert: dateString = monthNames [newValue.getUTCMonth ()] + "" + numberSuffix (newValue.getUTCDate ()) + "," + newValue.getUTCFullYear ();
Michael J. Calkins

9
Dies behandelt die Ausnahmen für die drei "Teen" -Nummern nicht richtig. Zum Beispiel können die Zahlen 111, 112und 113führen sollte "111th", "112th"und die "113th"jeweils nicht die "111st", "112nd", und "113rd"durch die Funktion , wie sie derzeit hergestellt codiert.
Martineau

3
Diese Antwort scheint sich perfekt entwickelt zu haben. Vielen Dank an alle Mitwirkenden.
Lonnie Best

7
Ich habe es ohne wirklichen Grund als ES6-Lambda gequetscht: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
@ Anomalie lustig genug, nach ~ π / 2 Jahren später kann ich es immer noch lesen.
Camilo Martin

210

Von 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
Das Hinzufügen einer Erklärung kann zu einer besseren Antwort führen!
Pugazh

5
@Pugazh A. finde s [v% 10] wenn> = 20 (20. ... 99.), B. wenn nicht gefunden, versuche s [v] (0...3.), C. wenn immer noch nicht gefunden, benutze s [0] (4. bis 19.)
Sheepy

4
Warum kommt das Double in den Funktionsnamen?
Gisheri

46

Minimaler einzeiliger Ansatz für Ordnungssuffixe

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

(Dies ist für positive ganze Zahlen, siehe unten für andere Variationen)

Erläuterung

Beginnen Sie mit einem Array mit den Suffixen ["st", "nd", "rd"]. Wir möchten Ganzzahlen, die mit 1, 2, 3 enden (aber nicht mit 11, 12, 13 enden), den Indizes 0, 1, 2 zuordnen.

Andere Ganzzahlen (einschließlich der mit 11, 12, 13 endenden) können auf alles andere abgebildet werden - Indizes, die nicht im Array gefunden wurden, werden ausgewertet undefined. Dies ist in Javascript falsch und bei Verwendung von logisch oder ( || "th") wird der Ausdruck "th"für diese Ganzzahlen zurückgegeben, was genau das ist, was wir wollen.

Der Ausdruck ((n + 90) % 100 - 10) % 10 - 1führt die Zuordnung durch. Brechen sie ab:

  • (n + 90) % 100: Dieser Ausdruck nimmt die Eingabe-Ganzzahl - 10 mod 100 und ordnet 10 bis 0, ... 99 bis 89, 0 bis 90, ..., 9 bis 99 zu. Jetzt sind die Ganzzahlen, die mit 11, 12, 13 enden, niedriger Ende (auf 1, 2, 3 abgebildet).
  • - 10: Jetzt wird 10 auf –10, 19 auf –1, 99 auf 79, 0 auf 80, ... 9 auf 89 abgebildet. Die Ganzzahlen, die mit 11, 12, 13 enden, werden auf negative Ganzzahlen (–9, –8, −7).
  • % 10: Jetzt werden alle Ganzzahlen, die mit 1, 2 oder 3 enden, auf 1, 2, 3 abgebildet. Alle anderen Ganzzahlen werden auf etwas anderes abgebildet (11, 12, 13 werden weiterhin auf –9, –8, –7 abgebildet).
  • - 1: Wenn Sie eins subtrahieren, erhalten Sie die endgültige Zuordnung von 1, 2, 3 zu 0, 1, 2.

Überprüfen, ob es funktioniert

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>

Variationen

Zulassen negativer Ganzzahlen:

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

In der ES6-Fat-Arrow-Syntax (anonyme Funktion):

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

Aktualisieren

Eine noch kürzere Alternative für positive ganze Zahlen ist der Ausdruck

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

In diesem Beitrag finden Sie eine Erklärung.

Update 2

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

3
elegant. mein Favorit.
Kerl Mograbi


10

Intl.PluralRules, die Standardmethode .

Ich möchte hier nur die kanonische Vorgehensweise fallen lassen, da niemand es zu wissen scheint.

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
Dies ist die einzig gute allgemeine Lösung, da hier nur negative Zahlen behandelt werden.
RobG

7

Sie haben nur 12 Tage? Ich wäre versucht, es zu einem einfachen Sucharray zu machen:

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

dann

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

oder

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

Danke, das hat mein Problem gelöst. Ich konnte das Suffix nicht an den Tag anpassen, also habe ich das Array nur mit den Zahlen und dem Suffix gefüllt, was perfekt funktioniert. Ich habe es dann einfach so genannt$("#dynamicTitle span").html(suffix[i-1]);
Antonio Vasilev

7

Durch die Zahl in ein Array aufteilen und umgekehrt wir einfach die letzten zwei Ziffern der Nummer überprüfen können mit array[0]und array[1].

Wenn eine Zahl im Teenageralter array[1] = 1ist, ist "th" erforderlich.

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

Dies ist perfekt. Vielen Dank!
Jason

Sie müssen 11, 12, 13
psx

2
@psx Dafür ist die Bedingung in Zeile 5.
Nick

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

Netter kleiner Oneliner, nur ein bisschen schwer zu verstehen
Bryc

Schlägt fehl, wenn n == 0 aufgrund eines n - 1Teils ist (gibt undefiniert zurück). Scheitert auch bei Zahlen größer als 110, z. B. getSuffix(111)gibt "st" zurück. Es löst zwar das Problem des OP, bei dem die Zahlen 1 bis 12 sind, ist jedoch keine allgemeine Lösung. :-(
RobG

2

Ich habe diese Funktion geschrieben, um dieses Problem zu lösen:

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

Mit diesem können Sie einfach .addSuffix()eine beliebige Zahl eingeben und es wird das ergeben, was Sie wollen. Beispielsweise:

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

Ich denke numberin dieser Zeichenfolge var lastDigits=n.substring(number.length-2);sollte geändert werden zuthis
Slava Abakumov

es sollte nstatt sein this, aber danke, dass du auf diesen Fehler hingewiesen hast! :)
Jimmery

2

Eine alternative Version der Ordnungsfunktion könnte wie folgt sein:

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

Die Variablen werden expliziter benannt, verwenden die Kamelfallkonvention und sind möglicherweise schneller.


Dies funktioniert jedoch nicht für lokalisierte Codebasen.
Daniel Harvey

1

Ich habe diese einfache Funktion neulich geschrieben. Obwohl Sie für ein Datum keine größeren Zahlen benötigen, werden auch höhere Werte berücksichtigt (1013., 36021. usw.)

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

Siehe kommentierte Version unter https://gist.github.com/furf/986113#file-annotated-js

Kurz, süß und effizient, genau wie Utility-Funktionen sein sollten. Funktioniert mit jeder vorzeichenbehafteten / vorzeichenlosen Ganzzahl / Float. (Auch wenn ich mir keine Notwendigkeit vorstellen kann, Floats zu ordinieren)


0

Hier ist eine weitere Option.

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

Beachten Sie die Ausnahme für die Teenager? Jugendliche sind so akward!

Edit: 11. und 12. vergessen


0

Ich wollte eine funktionale Antwort auf diese Frage geben, um die bestehende Antwort zu ergänzen:

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)

Wir haben ein Array mit speziellen Werten erstellt. Wichtig ist, dass Arrays einen auf Null basierenden Index haben, sodass ordinalSuffix [0] gleich 'st' ist.

Unsere Funktion numberToOrdinal prüft, ob die Zahl mit einer Teen-Zahl endet. In diesem Fall wird die Zahl mit 'th' angehängt, da alle Ordnungszahlen dann 'th' sind. Für den Fall, dass die Zahl kein Teenager ist, übergeben wir die Zahl an addSuffix, das die Zahl zur Ordnungszahl hinzufügt, die dadurch bestimmt wird, ob die Zahl minus 1 (weil wir einen auf Null basierenden Index verwenden) mod 10 einen Rest von 2 hat oder weniger wird es aus dem Array genommen, sonst ist es 'th'.

Beispielausgabe:

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

Altes, das ich für meine Sachen gemacht habe ...

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

Fügen Sie eine Beschreibung des obigen Codes hinzu. Es würde viel mehr als nur ein Stück Code helfen.
Mathews Sunny


0

Ich habe diese Funktion für höhere Zahlen und alle Testfälle geschrieben

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

Hier ist ein etwas anderer Ansatz (ich glaube nicht, dass die anderen Antworten dies tun). Ich bin mir nicht sicher, ob ich es liebe oder hasse, aber es funktioniert!

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

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

0

Dies ist für einen Liner und Liebhaber von 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

Eine andere Option für + be number wäre:

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

Um das Ordnungspräfix zu entfernen, verwenden Sie einfach diese:

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

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

Fühlen Sie sich frei, nach Ihren Wünschen zu ändern


0

Sie können die scales::ordinal()Funktion auch verwenden . Es ist schnell und einfach zu bedienen.

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

-1

Ich kann das nur empfehlen, es ist super einfach und unkompliziert zu lesen. Ich hoffe es hilft?

  • Es vermeidet die Verwendung einer negativen Ganzzahl, dh einer Zahl kleiner als 1, und gibt false zurück
  • Es gibt 0 zurück, wenn die Eingabe 0 ist
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));

AUSGABE

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

-7

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

Sie können verwenden

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

zum Positionieren des Suffixes


4
Dies ist nicht das, wonach das OP gefragt hat
TetraDev
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.