st、nd、rd、th(序数)サフィックスを数値に追加する


150

現在の日付に基づいてテキストの文字列を動的に生成したいと思います。したがって、たとえば、1日目である場合、コードで「 "<動的> 1 * <動的文字列> st </動的文字列> * </動的>"」を生成します。

合計12日あるので、次のようにしました。

  1. 12日間ループするforループを設定しました。

  2. 私のhtmlで、それをターゲットにする一意のIDを要素に与えました。以下を参照してください。

    <h1 id="dynamicTitle" class="CustomFont leftHeading shadow">On The <span></span> <em>of rest of generic text</em></h1>
  3. 次に、私のforループ内に次のコードがあります。

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

更新

これは、要求されたforループ全体です。

$(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
ソースコードが十分に短い場合、完全なものを投稿し、何が間違っているのか、何が混乱しているのかを正確に述べていただけませんか?
RonaldBarzell 2012年

あなたのコードが現在やっていないことは何ですか?あなたは何が悪いのかはっきりと述べていませんでした。
先のとがった

表示されているコードはif、ループにさらに含まれているブロックのコンテンツであると思いますか?さらにコードを表示....
MrCode

@MrCode-はい、あなたは正しいです。forループ全体を含むように投稿を更新しました。これで問題が解決することを願っています!
アントニオヴァ

きちんとそれはうまくいきます。
Dan Jay

回答:


345

ルールは以下の通りです。

  • stは、1で終わる数字で使用されます(たとえば、1番目、最初に発音)
  • ndは2で終わる数値で使用されます(たとえば、92nd、90秒と発音)
  • rdは、3で終わる数字とともに使用されます(たとえば、33番目、33番目の発音)
  • 上記のルールの例外として、11、12、または13で終わるすべての「10の」数字は-thを使用します(たとえば、11番目、11番目、112番目、100番目、および12番目の発音)
  • thは他のすべての数値に使用されます(たとえば、9番目、9番目の発音)。

次のJavaScriptコード(Jun '14で書き換えられた)はこれを実現します。

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の数値の出力例:

  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
私の場合も同様にうまくいきました:dateString = monthNames [newValue.getUTCMonth()] + "" + numberSuffix(newValue.getUTCDate())+ "、" + newValue.getUTCFullYear();
マイケルJ.

9
これは、3つの「十代」の数値の例外を適切に処理しません。例えば番号111112、及び113をもたらすべきである"111th""112th""113th"それぞれしない"111st""112nd""113rd"現在符号化としての機能によって生成されます。
martineau 14年

3
この答えは完全に進化したようです。すべての貢献者に感謝します。
ロニーベスト

7
私は本当の理由もなくそれをES6ラムダとしてsqeezeしました: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はおかしなことに、π/ 2年後もまだ読むことができます。
カミロマーティン

210

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
説明を追加すると、より適切な回答になります!
Pugazh

5
@Pugazh A.の検索S [v%と10]> = 20(20 ... 99)であれば、B.見つからない場合、トライS [V](0th..3rd)、C.まだ見つからない場合、使用の[0](4
19

4
なぜダブルが関数名を取得するのですか?
ギシェリ

46

序数接尾辞の最小限の1行アプローチ

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

(これは正の整数用です。他のバリエーションについては以下を参照してください)

説明

接尾辞が付いた配列から始めます["st", "nd", "rd"]。1、2、3で終わる(11、12、13で終わらない)整数をインデックス0、1、2にマッピングします。

その他の整数(11、12、13で終わるものを含む)は他の整数にマップできますundefined。配列にないインデックスはと評価されます。これはJavaScriptで不正であり、logicalまたは(|| "th")を使用すると"th"、これらの整数に対して式が返されます。これはまさに私たちが望むものです。

((n + 90) % 100 - 10) % 10 - 1がマッピングを行います。それを分解する:

  • (n + 90) % 100:この式は、入力整数を受け取ります-10 mod 100、10から0、... 99から89、0から90、...、9から99をマッピングします。11、12、13で終わる整数は、終了(1、2、3にマップ)。
  • - 10:10が-10、19から-1、99から79、0から80、... 9から89にマッピングされます。11、12、13で終わる整数は負の整数(-9、-8、 −7)。
  • % 10:1、2、または3で終わるすべての整数は1、2、3にマップされます。他のすべての整数は別のものにマップされます(11、12、13は引き続き-9、-8、-7にマップされます)。
  • - 1:1を減算すると、1、2、3から0、1、2の最終的なマッピングが得られます。

動作することを確認する

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>

バリエーション

負の整数を許可:

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

ES6ファットアロー構文(無名関数)の場合:

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

更新

正の整数のさらに短い代替は次の式です

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

説明については、この投稿を参照してください。

アップデート2

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

3
エレガント。お気に入り。
モグラビ男16年


10

Intl.PluralRules標準的な方法です。

誰もそれを知らないようであるので、私はこれをここで標準的な方法でやめたいと思います。

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
これは、負の数を処理する唯一の回答であるため、唯一の優れた一般的なソリューションです。
RobG

7

12日しかないの?私はそれを単純なルックアップ配列にしたくなります:

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

その後

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

または

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

おかげで、これで私の問題は解決しました。私はサフィックスをその日と一致させることができなかったので、配列と完全に機能するサフィックスの両方を入力しました。それから私は単にそれを次のように呼びました$("#dynamicTitle span").html(suffix[i-1]);
アントニオ・ヴァシレフ'29

7

数値を配列に分割して逆にすることで、array[0]およびを使用して、数値の最後の2桁を簡単に確認できます。array[1]

数字が10代のarray[1] = 1場合、「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";
}

これは完璧です。ありがとう!
Jason

11、12、13を除外する必要があります
psx 2018年

2
@psxこれが5行目の条件です。
ニック

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

素敵な小さなワンライナー、理解するのが少し難しい
bryc

n - 1一部のためにn == 0で失敗します(未定義を返します)。110より大きい数値の場合も失敗しますgetSuffix(111)。たとえば、「st」を返します。これは、数値が1〜12であるOPの問題を解決しますが、一般的な解決策ではありません。:-(
RobG

2

私はこの問題を解決するためにこの関数を書きました:

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

これを使用すると.addSuffix()、任意の数に置くことができ、必要な結果が得られます。例えば:

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

numberこの文字列var lastDigits=n.substring(number.length-2);を次のように変更する必要があると思いますthis
スラバアバクモフ

n代わりにすべきですがthis、そのバグを指摘してくれてありがとう!:)
Jimmery 2013年

2

序数関数の代替バージョンは次のとおりです。

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

変数はより明確に名前が付けられ、キャメルケースの規則を使用しており、より高速である可能性があります。


ただし、ローカライズされたコードベースでは機能しません。
ダニエルハーベイ

1

先日、この簡単な関数を書きました。日付には大きな数値は必要ありませんが、これはより高い値(1013番目、36021番目など)にも対応します。

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

https://gist.github.com/furf/986113#file-annotated-jsで注釈付きバージョンを参照してください

ユーティリティ関数と同じように、短く、甘く、効率的です。符号付き/符号なし整数/浮動小数点で動作します。(フロートを序数化する必要性は想像できませんが)


0

これは別のオプションです。

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

十代の若者たちの例外に気づきましたか?十代の若者たちはとても厄介です!

編集:11日と12日について忘れました


0

既存の回答を補足するために、この質問に対する機能的な回答を提供したいと思いました。

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)

特別な値の配列を作成しました。覚えておくべき重要なことは、配列にはゼロベースのインデックスがあるため、ordinalSuffix [0]は「st」に等しいということです。

関数numberToOrdinalは、数値が10進数で終わるかどうかをチェックします。この場合、数値の序数は「th」であるため、数値に「th」を追加します。数値が10代でない場合は、数値を序数に追加するaddSuffixに数値を渡します。これは、数値から1を引いた値(0から始まるインデックスを使用しているため)mod 10の余りが2であるかどうかによって決まります。それ以下の場合は配列から取得され、それ以外の場合は「th」です。

出力例:

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

私が自分のもののために作った古いもの...

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

上記のコードに関する説明を追加します。それはコードの断片よりもはるかに役立つでしょう。
Mathews Sunny、

0

優れたdate-fnsライブラリを強くお勧めします。高速、モジュール式、不変、標準の日付で機能します。

import * as DateFns from 'date-fns';

const ordinalInt = DateFns.format(someInt, 'do');

date-fnsのドキュメントを参照してください:https ://date-fns.org/v2.0.0-alpha.9/docs/format


0

この関数は、より大きな数値とすべてのテストケース用に作成しました

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

ここに少し異なるアプローチがあります(他の答えはこれを行うとは思いません)。好きか嫌いかはわかりませんが、うまくいきます!

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

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

0

これは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

+ be番号の別のオプションは次のとおりです。

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

また、序数の接頭辞を取り除くには、これらを使用してください:

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

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

必要に応じて自由に変更してください


0

scales::ordinal()関数を使用することもできます。使用は高速でシンプルです。

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

-1

私はこれを強くお勧めします。読むのはとても簡単で簡単です。お役に立てれば幸いです。

  • 負の整数、つまり1未満の数の使用を避け、falseを返します
  • 入力が0の場合は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));

出力

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

-7

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

使用できます

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

サフィックスを配置するため


4
これはOPが求めていたものではありません
TetraDev
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.