有没有在C#一个简单的方法来创建序数为多少?例如:
1返回1st
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时接受的答案不正确
////// Get the ordinal value of positive integers. /// ////// 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 /// /// The number. ///Ordinal value of positive integers, or 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()); }if less than 1.
简单,干净,快捷
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());
编辑于2013年12月12日例外.我从头顶说:-)
编辑为1011 - 其他人已经解决了这个问题,只是想确保其他人不会抓住这个不正确的版本.
我更喜欢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; } }
虽然我尚未对此进行基准测试,但您应该能够通过避免所有条件语句来获得更好的性能.
这是java,但是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语句解决方案那样可读.