在c#中有一个简单的方法来创建一个数字的序数吗?例如:
1返回第1位 2返回第2 3返回第3 等
这是否可以通过String.Format()来完成,或者是否有可用的函数来完成?
在c#中有一个简单的方法来创建一个数字的序数吗?例如:
1返回第1位 2返回第2 3返回第3 等
这是否可以通过String.Format()来完成,或者是否有可用的函数来完成?
当前回答
另一个一行程序,但是没有进行比较,只将正则表达式结果索引到数组中。
public static string GetOrdinalSuffix(int input)
{
return new []{"th", "st", "nd", "rd"}[Convert.ToInt32("0" + Regex.Match(input.ToString(), "(?<!1)[1-3]$").Value)];
}
PowerShell版本可以进一步缩短:
function ord($num) { return ('th','st','nd','rd')[[int]($num -match '(?<!1)[1-3]$') * $matches[0]] }
其他回答
根据其他答案:
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";
}
我很喜欢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;
}
}
虽然我还没有对此进行基准测试,但通过避免所有条件case语句,您应该能够获得更好的性能。
这是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语句解决方案那样可读。
本页为您提供了所有自定义数字格式规则的完整列表:
自定义数字格式字符串
如你所见,这里没有关于序数的内容,所以不能使用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()方法。
还要注意,这不是国际化的。我不知道其他语言中的序数是什么样子。
private static string GetOrd(int num) => $"{num}{(!(Range(11, 3).Any(n => n == num % 100) ^ Range(1, 3).All(n => n != num % 10)) ? new[] { "ˢᵗ", "ⁿᵈ", "ʳᵈ" }[num % 10 - 1] : "ᵗʰ")}";
如果有人在找一句俏皮话。