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

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

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


当前回答

c# 8和9中接受的带有开关表达式和模式匹配的答案。

没有不必要的字符串转换或分配。

string.Concat(number, number < 0 ? "" : (number % 100) switch 
{   
    11 or 12 or 13 => "th", 
    int n => (n % 10) switch 
    { 
        1 => "st", 
        2 => "nd", 
        3 => "rd", 
        _ => "th", 
    }
})

或者是不友好的一句话:

$"{number}{(number < 0 ? "" : (number % 100) switch { 11 or 12 or 13 => "th", int n => (n % 10) switch { 1 => "st", 2 => "nd", 3 => "rd", _ => "th" }})}"

其他回答

本页为您提供了所有自定义数字格式规则的完整列表:

自定义数字格式字符串

如你所见,这里没有关于序数的内容,所以不能使用String.Format。然而,编写一个函数来实现它并不难。

public static string AddOrdinal(int num)
{
    if( num <= 0 ) return num.ToString();

    switch(num % 100)
    {
        case 11:
        case 12:
        case 13:
            return num + "th";
    }
    
    switch(num % 10)
    {
        case 1:
            return num + "st";
        case 2:
            return num + "nd";
        case 3:
            return num + "rd";
        default:
            return num + "th";
    }
}

更新:从技术上讲,序数不存在<= 0,所以我更新了上面的代码。还删除了多余的ToString()方法。

还要注意,这不是国际化的。我不知道其他语言中的序数是什么样子。

这里是DateTime扩展类。复制,粘贴和享受

public static class DateTimeExtensions
{
    public static string ToStringWithOrdinal(this DateTime d)
    {
        var result = "";
        bool bReturn = false;            
        
        switch (d.Day % 100)
        {
            case 11:
            case 12:
            case 13:
                result = d.ToString("dd'th' MMMM yyyy");
                bReturn = true;
                break;
        }

        if (!bReturn)
        {
            switch (d.Day % 10)
            {
                case 1:
                    result = d.ToString("dd'st' MMMM yyyy");
                    break;
                case 2:
                    result = d.ToString("dd'nd' MMMM yyyy");
                    break;
                case 3:
                    result = d.ToString("dd'rd' MMMM yyyy");
                    break;
                default:
                    result = d.ToString("dd'th' MMMM yyyy");
                    break;
            }

        }

        if (result.StartsWith("0")) result = result.Substring(1);
        return result;
    }
}

结果:

2014年10月9日

要求“减少冗余”版本的samjudson的回答…

public static string AddOrdinal(int number)
{
    if (number <= 0) return number.ToString();

    string GetIndicator(int num)
    {
        switch (num % 100)
        {
            case 11:
            case 12:
            case 13:
                return "th";
        }

        switch (num % 10)
        {
            case 1:
                return "st";
            case 2:
                return "nd";
            case 3:
                return "rd";
            default:
                return "th";
        }
    }

    return number + GetIndicator(number);
}

c# 8和9中接受的带有开关表达式和模式匹配的答案。

没有不必要的字符串转换或分配。

string.Concat(number, number < 0 ? "" : (number % 100) switch 
{   
    11 or 12 or 13 => "th", 
    int n => (n % 10) switch 
    { 
        1 => "st", 
        2 => "nd", 
        3 => "rd", 
        _ => "th", 
    }
})

或者是不友好的一句话:

$"{number}{(number < 0 ? "" : (number % 100) switch { 11 or 12 or 13 => "th", int n => (n % 10) switch { 1 => "st", 2 => "nd", 3 => "rd", _ => "th" }})}"

简单、干净、快捷

private static string GetOrdinalSuffix(int num)
{
    string number = num.ToString();
    if (number.EndsWith("11")) return "th";
    if (number.EndsWith("12")) return "th";
    if (number.EndsWith("13")) return "th";
    if (number.EndsWith("1")) return "st";
    if (number.EndsWith("2")) return "nd";
    if (number.EndsWith("3")) return "rd";
    return "th";
}

或者更好的是,作为一个扩展方法

public static class IntegerExtensions
{
    public static string DisplayWithSuffix(this int num)
    {
        string number = num.ToString();
        if (number.EndsWith("11")) return number + "th";
        if (number.EndsWith("12")) return number + "th";
        if (number.EndsWith("13")) return number + "th";
        if (number.EndsWith("1")) return number + "st";
        if (number.EndsWith("2")) return number + "nd";
        if (number.EndsWith("3")) return number + "rd";
        return number + "th";
    }
}

现在你可以打电话了

int a = 1;
a.DisplayWithSuffix(); 

甚至直接到

1.DisplayWithSuffix();