Zobacz moją odpowiedź tutaj. stackoverflow.com/questions/69262/… To pytanie dotyczyło .NET, ale odpowiedziałem, podając rozwiązanie PHP, więc powinno ci pomóc.
nickf
Jedynym sposobem, w jaki mogę o tym pomyśleć, jest użycie instrukcji if dla każdej możliwej liczby, IE, if (1), a następnie "st" elseif (2), następnie "nd" itp. Itd. If (23000) then " nd ”. Jest to problem, jeśli masz duże liczby, ale możesz napisać program, który napisze kod za Ciebie, może zapętlić wszystkie liczby, wypisując ifs, abyś mógł skopiować i wkleić do kodu.
Tom Gullen
2
@Tom, tabela przeglądowa może być lepsza, po prostu zainicjuj ją 23000 wartościami i uzyskaj wartość o indeksie n, gdzie n to liczba, która ma być liczbą porządkową.
John Boker,
2
Pułkownik Shrapnel. możesz genialny, ale nie wszyscy. w każdym razie dziękuję za zainteresowanie moim pytaniem
ArK
@John, bardzo sprytny pomysł, dostęp do niego byłby bardzo szybki, ponieważ każdy indeks reprezentuje numer, który szukasz.
Chociaż na początku trochę trudne do zrozumienia, myślę, że teraz najlepiej oddaje sposób działania systemu przyrostków porządkowych w języku angielskim.
erisco
6
Podoba mi się twoje rozwiązanie. Dodatkowo, jeśli wolisz nie generować 0, zmień ostatnią linię na$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
Gavin Jackson
1
@GavinJackson Twój dodatek do tego doskonałego rozwiązania naprawdę mi pomógł (+1). Czy mógłbyś mi wyjaśnić, co się dzieje w obliczeniach? Chcę zrozumieć. Twoje zdrowie! EDYCJA: Znaleziono odpowiedź: operator warunkowy
Andrew Fox
Przepraszamy, musiałem złamać 111 głosów na 112: D Uruchomiono go w Delphi wraz z aplikacją demonstracyjną: pastebin.com/wvmz1CHY
Jerry Dodge
1
@HafezDivandari - czy na pewno? Właśnie przetestowany z 7.1.19 i wydaje się, że działa dobrze
@Aley, widzę. Yii ma wbudowany program formatujący, którego teraz używamy. heh
jhnferraris
20
Można to osiągnąć w jednym wierszu, wykorzystując podobną funkcjonalność wbudowanych funkcji daty / czasu PHP. Pokornie poddaję się:
Rozwiązanie:
function ordinalSuffix( $n ){return date('S',mktime(1,1,1,1,((($n>=10)+($n>=20)+($n==0))*10+ $n%10)));}
Szczegółowe wyjaśnienie:
Wbudowana date()funkcja ma logikę sufiksu do obsługi obliczeń n-tego dnia miesiąca. Sufiks jest zwracany, gdy Sjest podany w ciągu formatu:
date('S',?);
Ponieważ date()wymaga znacznika czasu (dla ?powyżej), będziemy przechodzić naszą całkowitą $njako dayparametr mktime()i wykorzystania manekina wartości 1dla hour, minute, second, i month:
date('S', mktime(1,1,1,1, $n ));
To faktycznie kończy się niepowodzeniem w przypadku wartości spoza zakresu dla dnia miesiąca (tj. $n > 31), Ale możemy dodać prostą logikę wbudowaną do ograniczenia $ndo 29:
Jak zauważył @donatJ, powyższe zawodzi powyżej 100 (np. „111st”), ponieważ >=20sprawdzenia zawsze zwracają prawdę. Aby zresetować je co stulecie, dodajemy filtr do porównania:
Podoba mi się to podejście, ale niestety nie działa :-( 30 miejsce wychodzi jako 30. 40. wychodzi jako 40. itd.
Flukey
1
Tak, przepraszam. Kiedy przeczytałem pytanie, które pomyślałem, hej, powinno to być możliwe za pomocą jednej linii kodu. I właśnie go przepisałem. Jak widać po moich zmianach, poprawiam się. Po trzeciej edycji wydaje mi się, że jest już gotowy. Przynajmniej wszystkie liczby od 1 do 150 ładnie wypisują się na moim ekranie.
Paul
Wygląda dobrze do 500! (nie testowałem tego dalej). Dobra robota! :-)
Zrobiłem funkcję, która nie opiera się na funkcji PHP, date();ponieważ nie jest to konieczne, ale także uczyniłem ją tak zwartą i tak krótką, jak myślę, że jest obecnie możliwa.
Kod : (łącznie 121 bajtów)
function ordinal($i){// PHP 5.2 and laterreturn($i.(($j=abs($i)%100)>10&&$j<14?'th':(($j%=10)>0&&$j<4?['st','nd','rd'][$j-1]:'th')));}
Bardziej zwarty kod poniżej.
Działa w następujący sposób :
printf("The %s hour.\n", ordinal(0));// The 0th hour.
printf("The %s ossicle.\n", ordinal(1));// The 1st ossicle.
printf("The %s cat.\n", ordinal(12));// The 12th cat.
printf("The %s item.\n", ordinal(-23));// The -23rd item.
Co warto wiedzieć o tej funkcji :
Zajmuje się ujemnymi liczbami całkowitymi tak samo jak dodatnimi liczbami całkowitymi i zachowuje znak.
Zwraca 11, 12, 13, 811, 812, 813 itd. Dla -naście liczb zgodnie z oczekiwaniami.
To nie sprawdza dziesiętne, ale zostawię je na miejscu (stosowanie floor($i), round($i)lub ceil($i)na początku końcowego instrukcji return).
Możesz również dodać format_number($i)na początku ostatniej instrukcji return, aby uzyskać liczbę całkowitą oddzieloną przecinkami (jeśli wyświetlasz tysiące, miliony itp.).
Możesz po prostu usunąć $iz początku instrukcji return, jeśli chcesz zwrócić tylko przyrostek porządkowy bez tego, co wprowadzisz.
Ta funkcja działa od wersji PHP 5.2 wydanej w listopadzie 2006 wyłącznie z powodu składni krótkich tablic. Jeśli masz wersję wcześniejszą, zaktualizuj ją, ponieważ jesteś prawie dziesięć lat nieaktualny! Jeśli to się nie uda, po prostu zamień in-line ['st', 'nd', 'rd']na tymczasową zmienną zawierającą array('st', 'nd', 'rd');.
Ta sama funkcja (bez zwracania danych wejściowych), ale rozstrzelony widok mojej krótkiej funkcji dla lepszego zrozumienia:
function ordinal($i){
$j = abs($i);// make negatives into positives
$j = $j%100;// modulo 100; deal only with ones and tens; 0 through 99if($j>10&& $j<14)// if $j is over 10, but below 14 (so we deal with 11 to 13)return('th');// always return 'th' for 11th, 13th, 62912th, etc.
$j = $j%10;// modulo 10; deal only with ones; 0 through 9if($j==1)// 1st, 21st, 31st, 971streturn('st');if($j==2)// 2nd, 22nd, 32nd, 582ndreturn('nd');// if($j==3)// 3rd, 23rd, 33rd, 253rdreturn('rd');return('th');// everything else will suffixed with 'th' including 0th}
Aktualizacja kodu :
Oto zmodyfikowana wersja, która jest krótsza o 14 pełnych bajtów (łącznie 107 bajtów):
function ordinal($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}
Lub tak krótko, jak to możliwe, będąc o 25 bajtów krótszym (łącznie 96 bajtów):
function o($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}
Dzięki tej ostatniej funkcji po prostu wywołaj, o(121);a zrobi dokładnie to samo, co inne funkcje, które wymieniłem.
Aktualizacja kodu nr 2 :
Ben i ja pracowaliśmy razem i zmniejszyliśmy to o 38 bajtów (łącznie 83 bajty):
function o($i){return$i.@(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}
Nie sądzimy, że może to być krótsze niż to! Chcąc jednak udowodnić, że się mylisz. :)
Oto kolejna bardzo krótka wersja korzystająca z funkcji daty. Działa dla dowolnej liczby (nie jest ograniczona liczbą dni miesiąca) i bierze pod uwagę, że * 11 * 12 * 13 nie ma formatu * 1 * 2 * 3.
Nie jestem pewien, co oferuje ta odpowiedź oprócz odpowiedzi Chintana Thummara. Cóż, sugeruje, że Chintan Thummar naruszył prawa autorskie, chyba że napisał kod u twojego źródła ...
Odpowiedzi:
z wikipedii :
Gdzie
$number
jest numer, który chcesz wpisać. Działa z dowolną liczbą naturalną.Jako funkcja:
źródło
$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
PHP ma do tego wbudowaną funkcjonalność . Obsługuje nawet internacjonalizację!
Zauważ, że ta funkcja jest dostępna tylko w PHP 5.3.0 i nowszych.
źródło
NumberFomatter file not found
. Jak sobie z tym poradziłeś?apt-get install php5-intl
Można to osiągnąć w jednym wierszu, wykorzystując podobną funkcjonalność wbudowanych funkcji daty / czasu PHP. Pokornie poddaję się:
Rozwiązanie:
Szczegółowe wyjaśnienie:
Wbudowana
date()
funkcja ma logikę sufiksu do obsługi obliczeń n-tego dnia miesiąca. Sufiks jest zwracany, gdyS
jest podany w ciągu formatu:Ponieważ
date()
wymaga znacznika czasu (dla?
powyżej), będziemy przechodzić naszą całkowitą$n
jakoday
parametrmktime()
i wykorzystania manekina wartości1
dlahour
,minute
,second
, imonth
:To faktycznie kończy się niepowodzeniem w przypadku wartości spoza zakresu dla dnia miesiąca (tj.
$n > 31
), Ale możemy dodać prostą logikę wbudowaną do ograniczenia$n
do 29:Jedyna wartość dodatnia( Maj 2017 ) to nie działa$n == 0
, ale można to łatwo naprawić, dodając 10 w tym specjalnym przypadku:Aktualizacja, maj 2017
Jak zauważył @donatJ, powyższe zawodzi powyżej 100 (np. „111st”), ponieważ
>=20
sprawdzenia zawsze zwracają prawdę. Aby zresetować je co stulecie, dodajemy filtr do porównania:Po prostu zapakuj go w funkcję dla wygody i gotowe!
źródło
Oto jedna linijka:
Prawdopodobnie najkrótsze rozwiązanie. Oczywiście można ją opakować funkcją:
Pozdrawiam, Paul
EDIT1: Korekta kodu od 11 do 13.
EDIT2: Korekta kodu dla 111, 211, ...
EDIT3: Teraz działa poprawnie również dla wielokrotności 10.
źródło
z http://www.phpro.org/examples/Ordinal-Suffix.html
źródło
Prosta i łatwa odpowiedź brzmi:
źródło
Napisałem to dla PHP4. Działa dobrze i jest dość ekonomiczne.
źródło
wystarczy zastosować daną funkcję.
źródło
Generalnie możesz tego użyć i wywołać echo get_placing_string (100);
źródło
Zrobiłem funkcję, która nie opiera się na funkcji PHP,
date();
ponieważ nie jest to konieczne, ale także uczyniłem ją tak zwartą i tak krótką, jak myślę, że jest obecnie możliwa.Kod : (łącznie 121 bajtów)
Bardziej zwarty kod poniżej.
Działa w następujący sposób :
Co warto wiedzieć o tej funkcji :
floor($i)
,round($i)
lubceil($i)
na początku końcowego instrukcji return).format_number($i)
na początku ostatniej instrukcji return, aby uzyskać liczbę całkowitą oddzieloną przecinkami (jeśli wyświetlasz tysiące, miliony itp.).$i
z początku instrukcji return, jeśli chcesz zwrócić tylko przyrostek porządkowy bez tego, co wprowadzisz.Ta funkcja działa od wersji PHP 5.2 wydanej w listopadzie 2006 wyłącznie z powodu składni krótkich tablic. Jeśli masz wersję wcześniejszą, zaktualizuj ją, ponieważ jesteś prawie dziesięć lat nieaktualny! Jeśli to się nie uda, po prostu zamień in-line
['st', 'nd', 'rd']
na tymczasową zmienną zawierającąarray('st', 'nd', 'rd');
.Ta sama funkcja (bez zwracania danych wejściowych), ale rozstrzelony widok mojej krótkiej funkcji dla lepszego zrozumienia:
Aktualizacja kodu :
Oto zmodyfikowana wersja, która jest krótsza o 14 pełnych bajtów (łącznie 107 bajtów):
Lub tak krótko, jak to możliwe, będąc o 25 bajtów krótszym (łącznie 96 bajtów):
Dzięki tej ostatniej funkcji po prostu wywołaj,
o(121);
a zrobi dokładnie to samo, co inne funkcje, które wymieniłem.Aktualizacja kodu nr 2 :
Ben i ja pracowaliśmy razem i zmniejszyliśmy to o 38 bajtów (łącznie 83 bajty):
Nie sądzimy, że może to być krótsze niż to! Chcąc jednak udowodnić, że się mylisz. :)
Mam nadzieję, że wszystkim się spodoba.
źródło
abs()
z modułem%
abs();
usuwa znak minus, którego potrzebowałem.Jeszcze krótsza wersja dla dat w miesiącu (do 31) zamiast używania mktime () i niewymagająca pecl intl:
lub proceduralnie:
Działa to oczywiście, ponieważ domyślny miesiąc, który wybrałem (styczeń), ma 31 dni.
Co ciekawe, jeśli spróbujesz go z lutym (lub kolejnym miesiącem bez 31 dni), uruchomi się ponownie przed końcem:
więc możesz liczyć do dni tego miesiąca ze specyfikatorem daty
t
w pętli: liczba dni w miesiącu.źródło
źródło
Znalazłem odpowiedź w PHP.net
źródło
Oto kolejna bardzo krótka wersja korzystająca z funkcji daty. Działa dla dowolnej liczby (nie jest ograniczona liczbą dni miesiąca) i bierze pod uwagę, że * 11 * 12 * 13 nie ma formatu * 1 * 2 * 3.
źródło
Podoba mi się ten mały fragment
TUTAJ
źródło