Есть ли простой способ в .NET получить "st", "nd", "rd" и "th" endings для чисел?

Мне интересно, есть ли метод или формат, который мне не хватает в.NET, чтобы преобразовать следующее:

   1 to 1st
   2 to 2nd
   3 to 3rd
   4 to 4th
  11 to 11th
 101 to 101st
 111 to 111th

У этой ссылки есть плохой пример основного принципа, связанного с написанием вашей собственной функции, но мне более любопытно, есть ли встроенная емкость, которую я пропускаю.

Решение

Ответ Скотта Гензельма является принятым, потому что он напрямую отвечает на вопрос.

Для решения, однако, см. Этот отличный ответ.

Ответ 1

Нет, встроенные возможности библиотеки базового класса .NET отсутствуют.

Ответ 2

Это функция, которая намного проще, чем вы думаете. Хотя для этого может существовать еще одна функция .NET, эта работа (написанная на PHP) выполняет эту работу. Это не должно быть слишком сложно переносить.

function ordinal($num) {
    $ones = $num % 10;
    $tens = floor($num / 10) % 10;
    if ($tens == 1) {
        $suff = "th";
    } else {
        switch ($ones) {
            case 1 : $suff = "st"; break;
            case 2 : $suff = "nd"; break;
            case 3 : $suff = "rd"; break;
            default : $suff = "th";
        }
    }
    return $num . $suff;
}

Ответ 3

@nickf: Здесь находится функция PHP в С#:

public static string Ordinal(int number)
{
    string suffix = String.Empty;

    int ones = number % 10;
    int tens = (int)Math.Floor(number / 10M) % 10;

    if (tens == 1)
    {
        suffix = "th";
    }
    else
    {
        switch (ones)
        {
            case 1:
                suffix = "st";
                break;

            case 2:
                suffix = "nd";
                break;

            case 3:
                suffix = "rd";
                break;

            default:
                suffix = "th";
                break;
        }
    }
    return String.Format("{0}{1}", number, suffix);
}

Ответ 4

Простой, чистый, быстрый

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

Или еще лучше, как метод расширения

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

Теперь вы можете просто позвонить

int a = 1;
a.DisplayWithSuffix(); 

или даже прямо как

1.DisplayWithSuffix();

Ответ 5

Это уже было рассмотрено, но я не уверен, как установить ссылку на него. Вот фрагмент кода:

    public static string Ordinal(this int number)
    {
        var ones = number % 10;
        var tens = Math.Floor (number / 10f) % 10;
        if (tens == 1)
        {
            return number + "th";
        }

        switch (ones)
        {
            case 1: return number + "st";
            case 2: return number + "nd";
            case 3: return number + "rd";
            default: return number + "th";
        }
    }

FYI: Это как метод расширения. Если ваша версия .NET меньше 3,5, просто удалите это ключевое слово

[EDIT]: Спасибо, что указали, что это неверно, что вы получаете для копирования/вставки кода:)

Ответ 6

Здесь версия функции Microsoft SQL Server:

CREATE FUNCTION [Internal].[GetNumberAsOrdinalString]
(
    @num int
)
RETURNS nvarchar(max)
AS
BEGIN

    DECLARE @Suffix nvarchar(2);
    DECLARE @Ones int;  
    DECLARE @Tens int;

    SET @Ones = @num % 10;
    SET @Tens = FLOOR(@num / 10) % 10;

    IF @Tens = 1
    BEGIN
        SET @Suffix = 'th';
    END
    ELSE
    BEGIN

    SET @Suffix = 
        CASE @Ones
            WHEN 1 THEN 'st'
            WHEN 2 THEN 'nd'
            WHEN 3 THEN 'rd'
            ELSE 'th'
        END
    END

    RETURN CONVERT(nvarchar(max), @num) + @Suffix;
END

Ответ 7

Я знаю, что это не ответ на вопрос OP, но поскольку я счел полезным поднять функцию SQL Server из этого потока, вот эквивалент Delphi (Pascal):

function OrdinalNumberSuffix(const ANumber: integer): string;
begin
  Result := IntToStr(ANumber);
  if(((Abs(ANumber) div 10) mod 10) = 1) then // Tens = 1
    Result := Result + 'th'
  else
    case(Abs(ANumber) mod 10) of
      1: Result := Result + 'st';
      2: Result := Result + 'nd';
      3: Result := Result + 'rd';
      else
        Result := Result + 'th';
    end;
end;

Есть ли..., -1-й, 0-й смысл?

Ответ 8

Другой вкус:

/// <summary>
/// Extension methods for numbers
/// </summary>
public static class NumericExtensions
{
    /// <summary>
    /// Adds the ordinal indicator to an integer
    /// </summary>
    /// <param name="number">The number</param>
    /// <returns>The formatted number</returns>
    public static string ToOrdinalString(this int number)
    {
        // Numbers in the teens always end with "th"

        if((number % 100 > 10 && number % 100 < 20))
            return number + "th";
        else
        {
            // Check remainder

            switch(number % 10)
            {
                case 1:
                    return number + "st";

                case 2:
                    return number + "nd";

                case 3:
                    return number + "rd";

                default:
                    return number + "th";
            }
        }
    }
}

Ответ 9

public static string OrdinalSuffix(int ordinal)
{
    //Because negatives won't work with modular division as expected:
    var abs = Math.Abs(ordinal); 

    var lastdigit = abs % 10; 

    return 
        //Catch 60% of cases (to infinity) in the first conditional:
        lastdigit > 3 || lastdigit == 0 || (abs % 100) - lastdigit == 10 ? "th" 
            : lastdigit == 1 ? "st" 
            : lastdigit == 2 ? "nd" 
            : "rd";
}

Ответ 10

else if (choice=='q')
{
    qtr++;

    switch (qtr)
    {
        case(2): strcpy(qtrs,"nd");break;
        case(3):
        {
           strcpy(qtrs,"rd");
           cout<<"End of First Half!!!";
           cout<<" hteam "<<"["<<hteam<<"] "<<hs;
           cout<<" vteam "<<" ["<<vteam;
           cout<<"] ";
           cout<<vs;dwn=1;yd=10;

           if (beginp=='H') team='V';
           else             team='H';
           break;
       }
       case(4): strcpy(qtrs,"th");break;

Ответ 11

Я думаю, что порядковый суффикс трудно получить... вам в основном нужно написать функцию, которая использует переключатель для проверки чисел и добавления суффикса.

Нет никаких оснований для языка, который бы предоставлял это внутренне, особенно когда он специфичен для локали.

Вы можете сделать немного лучше, чем эта ссылка, когда дело доходит до количества кода для записи, но вам нужно закодировать функцию для этого...