在.NET 中有没有一种简单的方法来获得数字的“ st”、“ nd”、“ rd”和“ th”结尾?

我想知道是否有一个方法或格式字符串,我在.NET 缺少转换如下:

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

这个链接 有一个关于编写自己的函数所涉及的基本原则的糟糕例子,但是我更好奇的是,我是否缺少一个内置的功能。

解决方案

斯科特 · 汉塞尔曼的答案是公认的,因为它直接回答了这个问题。

但是,有关解决方案,请参见 这个伟大的答案

54895 次浏览

不,.NET 基类库中没有内置功能。

这个函数比你想象的要简单得多。虽然可能会有一个。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;
}

这个问题已经讨论过了,但是我不确定如何链接到它:

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

提示: 这是一个扩展方法。如果你的.NET 版本小于3.5,只需删除 This 关键字

[编辑] : 感谢指出它是不正确的,这就是你复制/粘贴代码:)

我认为序数后缀是很难得到... 你基本上必须写一个函数,使用一个开关来测试的数字,并添加后缀。

语言没有理由在内部提供这种功能,特别是当它是特定于地区的时候。

当涉及到需要编写的代码量时,您可以比这个链接做得更好一些,但是您必须为此编写一个函数..。

@ nickf: 这是 C # 中的 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);
}
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;

下面是一个 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

我知道这不是 OP 问题的答案,但是因为我发现从这个线程提取 SQLServer 函数很有用,所以这里有一个 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有意义吗?

简单,干净,快速

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

另一种口味:

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