Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
906
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Есть ли простой способ создать ординалы в C#?
Есть ли простой способ в 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" в зависимости от того, является ли вещь, которую вы считаете, мужской, женской или множественной!
Поэтому, если ваше программное обеспечение должно поддерживать разные языки, старайтесь избегать обычных языков.
Моя версия версии Джесси версии Стью и версии сэмюсона :)
Включен модульный тест, чтобы показать, что принятый ответ неверен, когда число < 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());
}
Тебе придется свернуть свой собственный. С самого верха моей головы:
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 - другие уже исправили это, просто хотят убедиться, что другие не схватят эту неправильную версию.
Мне очень понравились элементы из решений Стью и сэмюсона, и я объединил их в то, что я считаю полезным сочетанием:
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;
}
}
Просто, чисто, быстро
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();
Хотя я еще не провел сравнительный анализ этого, вы должны быть в состоянии получить лучшую производительность, избегая всех условных операторов 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 statement.
Похожее на решение Райана, но еще более простое, я просто использую простой массив и использую день, чтобы найти правильный порядковый номер:
private string[] ordinals = new string[] {"","st","nd","rd","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","th","st","nd","rd","th","th","th","th","th","th","th","st" };
DateTime D = DateTime.Now;
String date = "Today's day is: "+ D.Day.ToString() + ordinals[D.Day];
У меня не было необходимости, но я бы предположил, что вы можете использовать многомерный массив, если хотите иметь поддержку нескольких языков.
Из того, что я помню с моих дней в университете, этот метод требует минимальных усилий от сервера.