Подтвердить что ты не робот

Есть ли способ в Java преобразовать целое число в его порядковый номер?

Я хочу взять целое число и получить его порядковый номер, т.е.:

1 -> "First"
2 -> "Second"
3 -> "Third"
...
4b9b3361

Ответ 1

Если вы в порядке с "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

Ответ 2

Используя отличный ICU4J (там также отличная версия C), вы также можете сделать это и получить Ординалы как простые слова;

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

Ответ 3

Другое решение

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: не однострочный...

Ответ 5

В 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];
}

Ответ 6

Я выяснил, как сделать это на Android довольно простым способом. Все, что вам нужно сделать, это добавить зависимость в файл app 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

Ответ 7

Богемианский ответ очень хорош, но я рекомендую улучшить обработку ошибок. Если исходная версия ординала, если вы укажете отрицательное целое число, будет выбрано ArrayIndexOutOfBoundsException. Я думаю, что моя версия ниже ясна. Я надеюсь, что junit также полезен, поэтому нет необходимости визуально проверять вывод.

public class FormattingUtils {

    /**
     * Return the ordinal of a cardinal number (positive integer) (as per common usage rather than set theory).
     * {@link http://stackoverflow.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);
    }

}

Ответ 8

В 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

Ответ 9

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

Ответ 10

Я получил длинную, сложную, но понятную концепцию

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


}

Ответ 11

Лучший и простой способ, здесь мы идем:

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

Ответ 12

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