Есть ли способ в Java, чтобы преобразовать целое число в его порядковый номер?
Я хочу взять целое число и получить его порядковый номер, то есть:
1 -> "First"
2 -> "Second"
3 -> "Third"
...
14 ответов
Если вы согласны с "1-й", "2-й", "3-й" и т. Д., Вот простой код, который будет правильно обрабатывать любое целое число:
public static String ordinal(int i) {
String[] sufixes = new String[] { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" };
switch (i % 100) {
case 11:
case 12:
case 13:
return i + "th";
default:
return i + sufixes[i % 10];
}
}
Вот несколько тестов для крайних случаев:
public static void main(String[] args) {
int[] edgeCases = { 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 100, 101, 102, 103, 104, 111, 112, 113, 114 };
for (int edgeCase : edgeCases) {
System.out.println(ordinal(edgeCase));
}
}
Выход:
0th
1st
2nd
3rd
4th
5th
10th
11th
12th
13th
14th
20th
21st
22nd
23rd
24th
100th
101st
102nd
103rd
104th
111th
112th
113th
114th
Используя отличный ICU4J (есть также отличная версия на C), вы также можете сделать это и получить Ordinals в виде простых слов;
RuleBasedNumberFormat nf = new RuleBasedNumberFormat(Locale.UK, RuleBasedNumberFormat.SPELLOUT);
for(int i = 0; i <= 30; i++)
{
System.out.println(i + " -> "+nf.format(i, "%spellout-ordinal"));
}
например производит
0 -> zeroth
1 -> first
2 -> second
3 -> third
4 -> fourth
5 -> fifth
6 -> sixth
7 -> seventh
8 -> eighth
9 -> ninth
10 -> tenth
11 -> eleventh
12 -> twelfth
13 -> thirteenth
14 -> fourteenth
15 -> fifteenth
16 -> sixteenth
17 -> seventeenth
18 -> eighteenth
19 -> nineteenth
20 -> twentieth
21 -> twenty-first
22 -> twenty-second
23 -> twenty-third
24 -> twenty-fourth
25 -> twenty-fifth
26 -> twenty-sixth
27 -> twenty-seventh
28 -> twenty-eighth
29 -> twenty-ninth
30 -> thirtieth
Другое решение
public static String ordinal(int i) {
int mod100 = i % 100;
int mod10 = i % 10;
if(mod10 == 1 && mod100 != 11) {
return i + "st";
} else if(mod10 == 2 && mod100 != 12) {
return i + "nd";
} else if(mod10 == 3 && mod100 != 13) {
return i + "rd";
} else {
return i + "th";
}
}
Pro: не требует инициализации массива (меньше мусора)
Con: не один вкладыш...
Я понял, как сделать это в Android довольно простым способом. Все, что вам нужно сделать, это добавить зависимость к вашему app
"s build.gradle
файл:
implementation "com.ibm.icu:icu4j:53.1"
Далее создайте этот метод:
Котлин:
fun Number?.getOrdinal(): String? {
if (this == null) {
return null
}
val format = "{0,ordinal}"
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
android.icu.text.MessageFormat.format(format, this)
} else {
com.ibm.icu.text.MessageFormat.format(format, this)
}
}
Джава:
public static String getNumberOrdinal(Number number) {
if (number == null) {
return null;
}
String format = "{0,ordinal}";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return android.icu.text.MessageFormat.format(format, number);
} else {
return com.ibm.icu.text.MessageFormat.format(format, number);
}
}
Затем вы можете просто использовать его так:
Котлин:
val ordinal = 2.getOrdinal()
Джава:
String ordinal = getNumberOrdinal(2)
Как это устроено
Начиная с Android N (API 24) Android использует icu.text
вместо обычного java.text
( дополнительная информация здесь), которая уже содержит интернационализированную реализацию для порядковых чисел. Таким образом, решение очевидно простое - добавить icu4j
библиотека для проекта и использовать его в версиях ниже Nougat
В 1 строке:
public static String ordinal(int i) {
return i % 100 == 11 || i % 100 == 12 || i % 100 == 13 ? i + "th" : i + new String[]{"th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"}[i % 10];
}
Вот код для такого преобразования, а вот другой. И посмотрите на это ответы Как преобразовать число в слова в Java
Богемный ответ очень хороший, но я рекомендую улучшить обработку ошибок. В исходной версии ординала, если вы укажете отрицательное целое число, будет выдано исключение ArrayIndexOutOfBoundsException. Я думаю, что моя версия ниже яснее. Я надеюсь, что джунит также полезен, поэтому нет необходимости визуально проверять вывод.
public class FormattingUtils {
/**
* Return the ordinal of a cardinal number (positive integer) (as per common usage rather than set theory).
* {@link http://stackru.com/questions/6810336/is-there-a-library-or-utility-in-java-to-convert-an-integer-to-its-ordinal}
*
* @param i
* @return
* @throws {@code IllegalArgumentException}
*/
public static String ordinal(int i) {
if (i < 0) {
throw new IllegalArgumentException("Only +ve integers (cardinals) have an ordinal but " + i + " was supplied");
}
String[] sufixes = new String[] { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" };
switch (i % 100) {
case 11:
case 12:
case 13:
return i + "th";
default:
return i + sufixes[i % 10];
}
}
}
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class WhenWeCallFormattingUtils_Ordinal {
@Test
public void theEdgeCasesAreCovered() {
int[] edgeCases = { 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 100, 101, 102, 103, 104, 111, 112,
113, 114 };
String[] expectedResults = { "0th", "1st", "2nd", "3rd", "4th", "5th", "10th", "11th", "12th", "13th", "14th",
"20th", "21st", "22nd", "23rd", "24th", "100th", "101st", "102nd", "103rd", "104th", "111th", "112th",
"113th", "114th" };
for (int i = 0; i < edgeCases.length; i++) {
assertThat(FormattingUtils.ordinal(edgeCases[i])).isEqualTo(expectedResults[i]);
}
}
@Test(expected = IllegalArgumentException.class)
public void supplyingANegativeNumberCausesAnIllegalArgumentException() {
FormattingUtils.ordinal(-1);
}
}
private static String getOrdinalIndicator(int number) {
int mod = number;
if (number > 13) {
mod = number % 10;
}
switch (mod) {
case 1:
return "st";
case 2:
return "nd";
case 3:
return "rd";
default:
return "th";
}
}
static String getOrdinal(int input) {
if(input<=0) {
throw new IllegalArgumentException("Number must be > 0");
}
int lastDigit = input % 10;
int lastTwoDigit = input % 100;
if(lastTwoDigit >= 10 && lastTwoDigit <= 20) {
return input+"th";
}
switch (lastDigit) {
case 1:
return input+"st";
case 2:
return input+"nd";
case 3:
return input+"rd";
default:
return input+"th";
}
}
Я получил длинный, сложный, но легко понять концепцию
private static void convertMe() {
Scanner in = new Scanner(System.in);
try {
System.out.println("input a number to convert: ");
int n = in.nextInt();
String s = String.valueOf(n);
//System.out.println(s);
int len = s.length() - 1;
if (len == 0){
char lastChar = s.charAt(len);
if (lastChar == '1'){
System.out.println(s + "st");
} else if (lastChar == '2') {
System.out.println(s + "nd");
} else if (lastChar == '3') {
System.out.println(s + "rd");
} else {
System.out.println(s + "th");
}
} else if (len > 0){
char lastChar = s.charAt(len);
char preLastChar = s.charAt(len - 1);
if (lastChar == '1' && preLastChar != '1'){ //not ...11
System.out.println(s + "st");
} else if (lastChar == '2' && preLastChar != '1'){ //not ...12
System.out.println(s + "nd");
} else if (lastChar == '3' && preLastChar != '1'){ //not ...13
System.out.println(s + "rd");
} else {
System.out.println(s + "th");
}
}
} catch(InputMismatchException exception){
System.out.println("invalid input");
}
}
На всякий случай, если кто-то ищет версию расширения Kotlin :
fun Int.toEnOrdinal(): String {
val suffixes = arrayListOf("th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th")
return when (this % 100) {
11, 12, 13 -> "{$this}th"
else -> "$this" + suffixes[this % 10]
}
}
тогда все, что вам нужно сделать, это вызвать эту функцию на любом номере, например
5.toUKOrdinal()
-> 5-й
21.toUKOrdinal()
-> 21-е
так далее
В Scala для разнообразия,
List(1, 2, 3, 4, 5, 10, 11, 12, 13, 14 , 19, 20, 23, 33, 100, 113, 123, 101, 1001, 1011, 1013, 10011) map {
case a if (a % 10) == 1 && (a % 100) != 11 => a + "-st"
case b if (b % 10) == 2 && (b % 100) != 12 => b + "-nd"
case c if (c % 10) == 3 && (c % 100) != 13 => c + "-rd"
case e => e + "-th"
} foreach println
Лучший и простой способ, здесь мы идем:
import java.util.*;
public class Numbers
{
public final static String print(int num)
{
num = num%10;
String str = "";
switch(num)
{
case 1:
str = "st";
break;
case 2:
str = "nd";
break;
case 3:
str = "rd";
break;
default:
str = "th";
}
return str;
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter a number: ");
int number = sc.nextInt();
System.out.print(number + print(number));
}
}
public static String getOrdinalFor(int value) {
int tenRemainder = value % 10;
switch (tenRemainder) {
case 1:
return value+"st";
case 2:
return value+"nd";
case 3:
return value+"rd";
default:
return value+"th";
}
}