在c#中有一个简单的方法来创建一个数字的序数吗?例如:

1返回第1位 2返回第2 3返回第3 等

这是否可以通过String.Format()来完成,或者是否有可用的函数来完成?


当前回答

我很喜欢Stu和samjudson解决方案中的元素,并将它们结合在一起,形成了我认为可用的组合:

public static string Ordinal(this int number)
{
    const string TH = "th";
    var s = number.ToString();
    
    number %= 100;
    
    if ((number >= 11) && (number <= 13))
    {
        return s + TH;
    }
   
    switch (number % 10)
    {
        case 1:
            return s + "st";
        case 2:
            return s + "nd";
        case 3:
            return s + "rd";
        default:
            return s + TH;
    }
}

其他回答

我使用这个扩展类:

public static class Int32Extensions
{
    public static string ToOrdinal(this int i)
    {
        return (i + "th")
            .Replace("1th", "1st")
            .Replace("2th", "2nd")
            .Replace("3th", "3rd");
    }
}

Humanizer nuget包将为您提供帮助方法。免责声明,我是这个项目的贡献者。

Ordinalize将一个数字转换为一个序数字符串,用于表示在一个有序序列中的位置,例如1st, 2nd, 3rd, 4th:

1.Ordinalize() => "1st"
5.Ordinalize() => "5th"

你也可以对数字字符串调用Ordinalize函数,得到相同的结果:"21".Ordinalize() => "21st"

Ordinalize也支持两种形式的语法性别。 您可以将参数传递给Ordinalize,以指定数字应该以哪种性别输出。 可能的值为GrammaticalGender。男性,GrammaticalGender。女性和语法性别。中性:

// for Brazilian Portuguese locale
1.Ordinalize(GrammaticalGender.Masculine) => "1º"
1.Ordinalize(GrammaticalGender.Feminine) => "1ª"
1.Ordinalize(GrammaticalGender.Neuter) => "1º"
"2".Ordinalize(GrammaticalGender.Masculine) => "2º"
"2".Ordinalize(GrammaticalGender.Feminine) => "2ª"
"2".Ordinalize(GrammaticalGender.Neuter) => "2º"

显然,这只适用于某些文化。对于其他人来说,通过或不通过性别对结果没有任何影响。

此外,Ordinalize支持某些区域性应用的变体,这取决于序数在句子中的位置。 使用参数wordForm来获得一个或另一个结果。取值包括:WordForm。缩写和词形式。 你可以结合wordForm参数和性别参数,但是当它不适用时传入这个参数不会对结果产生任何影响。

// Spanish locale
1.Ordinalize(WordForm.Abbreviation) => "1.er" // As in "Vivo en el 1.er piso"
1.Ordinalize(WordForm.Normal) => "1.º" // As in "He llegado el 1º"
"3".Ordinalize(GrammaticalGender.Feminine, WordForm.Abbreviation) => "3.ª"
"3".Ordinalize(GrammaticalGender.Feminine, WordForm.Normal) => "3.ª"
"3".Ordinalize(GrammaticalGender.Masculine, WordForm.Abbreviation) => "3.er"
"3".Ordinalize(GrammaticalGender.Masculine, WordForm.Normal) => "3.º"

如果您想深入了解,请检查这些测试用例:OrdinalizeTests.cs

记得国际化!

这里的解决方案只适用于英语。如果您需要支持其他语言,事情就会变得复杂得多。

例如,在西班牙语中,“1st”可以写成“1”。o”、“1。”、“1。o”或“1”。比如“取决于你数的东西是阳性、阴性还是复数!”

因此,如果您的软件需要支持不同的语言,请尽量避免使用序数。

杰西版本的斯图和萨姆贾德森版本的我的版本:)

包含单元测试,以显示接受的答案是不正确的,当数字< 1

/// <summary>
/// Get the ordinal value of positive integers.
/// </summary>
/// <remarks>
/// Only works for english-based cultures.
/// Code from: http://stackoverflow.com/questions/20156/is-there-a-quick-way-to-create-ordinals-in-c/31066#31066
/// With help: http://www.wisegeek.com/what-is-an-ordinal-number.htm
/// </remarks>
/// <param name="number">The number.</param>
/// <returns>Ordinal value of positive integers, or <see cref="int.ToString"/> if less than 1.</returns>
public static string Ordinal(this int number)
{
    const string TH = "th";
    string s = number.ToString();

    // Negative and zero have no ordinal representation
    if (number < 1)
    {
        return s;
    }

    number %= 100;
    if ((number >= 11) && (number <= 13))
    {
        return s + TH;
    }

    switch (number % 10)
    {
        case 1: return s + "st";
        case 2: return s + "nd";
        case 3: return s + "rd";
        default: return s + TH;
    }
}

[Test]
public void Ordinal_ReturnsExpectedResults()
{
    Assert.AreEqual("-1", (1-2).Ordinal());
    Assert.AreEqual("0", 0.Ordinal());
    Assert.AreEqual("1st", 1.Ordinal());
    Assert.AreEqual("2nd", 2.Ordinal());
    Assert.AreEqual("3rd", 3.Ordinal());
    Assert.AreEqual("4th", 4.Ordinal());
    Assert.AreEqual("5th", 5.Ordinal());
    Assert.AreEqual("6th", 6.Ordinal());
    Assert.AreEqual("7th", 7.Ordinal());
    Assert.AreEqual("8th", 8.Ordinal());
    Assert.AreEqual("9th", 9.Ordinal());
    Assert.AreEqual("10th", 10.Ordinal());
    Assert.AreEqual("11th", 11.Ordinal());
    Assert.AreEqual("12th", 12.Ordinal());
    Assert.AreEqual("13th", 13.Ordinal());
    Assert.AreEqual("14th", 14.Ordinal());
    Assert.AreEqual("20th", 20.Ordinal());
    Assert.AreEqual("21st", 21.Ordinal());
    Assert.AreEqual("22nd", 22.Ordinal());
    Assert.AreEqual("23rd", 23.Ordinal());
    Assert.AreEqual("24th", 24.Ordinal());
    Assert.AreEqual("100th", 100.Ordinal());
    Assert.AreEqual("101st", 101.Ordinal());
    Assert.AreEqual("102nd", 102.Ordinal());
    Assert.AreEqual("103rd", 103.Ordinal());
    Assert.AreEqual("104th", 104.Ordinal());
    Assert.AreEqual("110th", 110.Ordinal());
    Assert.AreEqual("111th", 111.Ordinal());
    Assert.AreEqual("112th", 112.Ordinal());
    Assert.AreEqual("113th", 113.Ordinal());
    Assert.AreEqual("114th", 114.Ordinal());
    Assert.AreEqual("120th", 120.Ordinal());
    Assert.AreEqual("121st", 121.Ordinal());
    Assert.AreEqual("122nd", 122.Ordinal());
    Assert.AreEqual("123rd", 123.Ordinal());
    Assert.AreEqual("124th", 124.Ordinal());
}

根据其他答案:

public static string Ordinal(int n)
{   
    int     r = n % 100,     m = n % 10;

    return (r<4 || r>20) && (m>0 && m<4) ? n+"  stndrd".Substring(m*2,2) : n+"th";                                              
}