在c#中有一个简单的方法来创建一个数字的序数吗?例如:
1返回第1位 2返回第2 3返回第3 等
这是否可以通过String.Format()来完成,或者是否有可用的函数来完成?
在c#中有一个简单的方法来创建一个数字的序数吗?例如:
1返回第1位 2返回第2 3返回第3 等
这是否可以通过String.Format()来完成,或者是否有可用的函数来完成?
当前回答
简单、干净、快捷
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();
其他回答
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] : "ᵗʰ")}";
如果有人在找一句俏皮话。
编辑:正如YM_Industries在评论中指出的那样,samjudson的答案确实适用于超过1000的数字,nickf的评论似乎已经消失了,我不记得我看到的问题是什么。留下这个答案在这里比较时间。
正如nickf在评论中指出的(编辑:现在丢失了),很多数字> 999都不起作用。
以下是一个基于samjudson的公认答案的修改版本。
public static String GetOrdinal(int i)
{
String res = "";
if (i > 0)
{
int j = (i - ((i / 100) * 100));
if ((j == 11) || (j == 12) || (j == 13))
res = "th";
else
{
int k = i % 10;
if (k == 1)
res = "st";
else if (k == 2)
res = "nd";
else if (k == 3)
res = "rd";
else
res = "th";
}
}
return i.ToString() + res;
}
同样,Shahzad Qureshi使用字符串操作的回答也很好,但它确实有性能损失。为了生成大量这样的类型,LINQPad示例程序使字符串版本比整数版本慢6-7倍(尽管您必须生成很多才会注意到)。
LINQPad例子:
void Main()
{
"Examples:".Dump();
foreach(int i in new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 22, 113, 122, 201, 202, 211, 212, 2013, 1000003, 10000013 })
Stuff.GetOrdinal(i).Dump();
String s;
System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
for(int iter = 0; iter < 100000; iter++)
foreach(int i in new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 22, 113, 122, 201, 202, 211, 212, 2013, 1000003, 1000013 })
s = Stuff.GetOrdinal(i);
"Integer manipulation".Dump();
sw.Elapsed.Dump();
sw.Restart();
for(int iter = 0; iter < 100000; iter++)
foreach(int i in new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 22, 113, 122, 201, 202, 211, 212, 2013, 1000003, 1000013 })
s = (i.ToString() + Stuff.GetOrdinalSuffix(i));
"String manipulation".Dump();
sw.Elapsed.Dump();
}
public class Stuff
{
// Use integer manipulation
public static String GetOrdinal(int i)
{
String res = "";
if (i > 0)
{
int j = (i - ((i / 100) * 100));
if ((j == 11) || (j == 12) || (j == 13))
res = "th";
else
{
int k = i % 10;
if (k == 1)
res = "st";
else if (k == 2)
res = "nd";
else if (k == 3)
res = "rd";
else
res = "th";
}
}
return i.ToString() + res;
}
// Use string manipulation
public 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";
}
}
FWIW,对于MS-SQL,这个表达式将完成工作。将第一个WHEN (WHEN num % 100 IN (11,12,13) THEN 'th')作为列表中的第一个,因为这依赖于在其他尝试之前尝试。
CASE
WHEN num % 100 IN (11, 12, 13) THEN 'th' -- must be tried first
WHEN num % 10 = 1 THEN 'st'
WHEN num % 10 = 2 THEN 'nd'
WHEN num % 10 = 3 THEN 'rd'
ELSE 'th'
END AS Ordinal
对于Excel:
=MID("thstndrdth",MIN(9,2*RIGHT(A1)*(MOD(A1-11,100)>2)+1),2)
表达式(MOD(A1- 11100)>2)对于除以11,12,13结尾的任何数字(FALSE = 0)外的所有数字都是TRUE(1)。因此2 * RIGHT(A1) * (MOD(A1- 11100)>2) +1)对于11/12/13最终为1,否则: 1等于3 2点到5点, 3至7点 其他:9 -所需的2个字符从该位置开始的“第thstndrdth”中选择。
如果你真的想把它直接转换成SQL,这对我来说适用于一些测试值:
DECLARE @n as int
SET @n=13
SELECT SubString( 'thstndrdth'
, (SELECT MIN(value) FROM
(SELECT 9 as value UNION
SELECT 1+ (2* (ABS(@n) % 10) * CASE WHEN ((ABS(@n)+89) % 100)>2 THEN 1 ELSE 0 END)
) AS Mins
)
, 2
)
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";
}
这是dart中的实现,可以根据语言进行修改。
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";
}