C #에서 서수를 만드는 쉬운 방법이 있습니까? 반환 2는 2를 반환 3은 3을 반환 …기타 이 작업을 수행

C #에서 숫자에 대한 서수 를 만드는 쉬운 방법이 있습니까? 예를 들면 다음과 같습니다.

  • 1은 1을 반환
  • 2는 2를 반환
  • 3은 3을 반환
  • …기타

이 작업을 수행 할 수 있습니까 String.Format()? 아니면이를 수행 할 수있는 기능이 있습니까?



답변

이 페이지는 모든 사용자 지정 숫자 서식 규칙의 전체 목록을 제공합니다.

http://msdn.microsoft.com/en-us/library/0c899ak8.aspx

보시다시피 서수에 대해서는 아무것도 없으므로 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()방법 도 제거했습니다 .

또한 국제화되지 않았습니다. 나는 다른 언어에서 서 수가 어떻게 생겼는지 전혀 모른다.


답변

국제화를 기억하십시오!

이 솔루션은 영어로만 작동합니다. 다른 언어를 지원해야 할 경우 상황이 훨씬 복잡해집니다.

예를 들어 스페인어에서 “1st”는 세는 것이 남성적이든 여성적이든 복수형인지에 따라 “1.o”, “1.a”, “1.os”또는 “1.as”로 작성됩니다. !

따라서 소프트웨어가 다른 언어를 지원해야하는 경우 서수를 피하십시오.


답변

Jesse 버전의 Stu 및 samjudson 버전 🙂

숫자 <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());
    }


답변

간단하고 깨끗하며 빠릅니다.

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


답변

당신은 자신의 롤을해야합니다. 내 머리 꼭대기에서 :

public static string Ordinal(this int number)
{
  var work = number.ToString();
  if ((number % 100) == 11 || (number % 100) == 12 || (number % 100) == 13)
    return work + "th";
  switch (number % 10)
  {
    case 1: work += "st"; break;
    case 2: work += "nd"; break;
    case 3: work += "rd"; break;
    default: work += "th"; break;
  }
  return work;
}

그런 다음 할 수 있습니다

Console.WriteLine(432.Ordinal());

11/12/13 예외에 대해 편집되었습니다. 나는 내 머리 꼭대기에서 말했다 🙂

1011로 편집 됨-다른 사람들은 이미이 문제를 해결했습니다. 다른 사람들 이이 잘못된 버전을 잡지 않도록하십시오.


답변

나는 Stusamjudson 의 솔루션 모두에서 요소를 좋아 했으며 사용 가능한 콤보라고 생각하는 요소로 함께 작동했습니다.

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


답변

아직 벤치마킹하지는 않았지만 모든 조건부 사례를 피함으로써 더 나은 성능을 얻을 수 있어야합니다.

이것은 자바이지만 C #으로의 포트는 간단합니다.

public class NumberUtil {
  final static String[] ORDINAL_SUFFIXES = {
    "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
  };

  public static String ordinalSuffix(int value) {
    int n = Math.abs(value);
    int lastTwoDigits = n % 100;
    int lastDigit = n % 10;
    int index = (lastTwoDigits >= 11 && lastTwoDigits <= 13) ? 0 : lastDigit;
    return ORDINAL_SUFFIXES[index];
  }

  public static String toOrdinal(int n) {
    return new StringBuffer().append(n).append(ordinalSuffix(n)).toString();
  }
}

엄격한 루프에서 많은 서수를 생성하는 경우 조건부 감소 및 배열 조회를 사용하면 성능이 향상됩니다. 그러나 나는 이것이 case statement 솔루션만큼 읽을 수 없다는 것을 인정합니다.