Jak mogę wyprowadzać zera wiodące w Rubim?


238

Wyprowadzam zestaw plików numerowanych ze skryptu Ruby. Liczby pochodzą z inkrementacji licznika, ale aby ładnie je sortować w katalogu, chciałbym używać początkowych zer w nazwach plików. Innymi słowy

plik_001 ...

zamiast

plik_1

Czy istnieje prosty sposób dodawania zer wiodących podczas konwersji liczby na ciąg? (Wiem, że mogę zrobić „jeśli mniej niż 10 .... jeśli mniej niż 100”).

Odpowiedzi:


281

Jeśli znana jest maksymalna liczba cyfr w liczniku (np. N = 3 dla liczników 1..876), możesz to zrobić

str = "file_" + i.to_s.rjust(n, "0")

8
Heh heh, nie najlepsza odpowiedź, ale nie wiedziałem o rjust i używam rubinu od lat. Twoje zdrowie!
pauliephonic

Muszę zagłosować, bo wydaje się, że% 03s wstawia spacje z jakiegoś dziwnego powodu (% 03d wydaje się działać dobrze). W obu przypadkach mogłem przysiąc, że C był wypełniony zerami.
Nerdmaster

W końcu zmieniłem to na akceptowaną odpowiedź, ponieważ jest najprostsza i najłatwiejsza do zapamiętania. %działa, ale ma bardziej ogólny cel.
Nathan Long

nieoczekiwany, ale najłatwiejszy
akostadinov

1
Przybyłem tutaj, aby wpisać numer 36. To działa, podczas gdy% wygląda na to, że nie. Dzięki!
Ethan Kamiński

344

Użyj %operatora z ciągiem znaków:

irb(main):001:0> "%03d" % 5
=> "005"

Lewa strona to ciąg formatu printf, a prawa strona może być listą wartości, więc możesz zrobić coś takiego:

irb(main):002:0> filename = "%s/%s.%04d.txt" % ["dirname", "filename", 23]
=> "dirname/filename.0023.txt"

Oto ściągawka w formacie printf , która może być przydatna w tworzeniu ciągu formatu. Format printf pochodzi pierwotnie z Cfunkcji printf, ale podobne funkcje formatowania są dostępne w Perlu, Ruby, Pythonie, Javie, PHP itp.


1
Wspaniały! Zatem „% s” oznacza „zastąp tutaj N-tą wartość”, a „% 03d” oznacza „zastąp tutaj liczbę, dodając tyle zer, ile potrzeba, aby była to 3-cyfrowa liczba?” (Zgaduję, że d oznacza „cyfry”). Widzę teraz dokumentację na ten temat ( ruby-doc.org/core/classes/String.html#M000770 ), ale jest bardzo zwięzły i chciałbym trochę rozwinąć .
Nathan Long,

1
Dodałem link do ściągawki w formacie printf. „s” oznacza „ciąg”, „d” oznacza „liczbę dziesiętną”. „03” oznacza „pad do 3 znaków z zerami”; „% 3d” padnie po lewej stronie spacjami.
Daniel Martin,

2
BTW - to jest to samo, co dzwonienie Kernel#sprintf, co jest udokumentowane tutaj: ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf
Nathan Long

Dodając do komentarza @ NathanLong, pierwszy przykład w tej odpowiedzi zostałby zapisany jako sprintf("%03d", 5).
Dennis

To powinna być wybrana odpowiedź.
Dan Barron

50

Czy nie możesz po prostu sformatować ciągu wartości przed skonkatowaniem nazwy pliku?

"%03d" % number

Myślę, że ta odpowiedź nic nie dodaje do odpowiedzi @Daniela Martina, jednak podoba mi się jej prostota ...
svelandiag

3
Odpowiedział w tej samej minucie co Daniel Martin, więc prawdopodobnie nie wiedział o powielaniu.
Kurt Peek

Jest to idealne rozwiązanie dla utc_offset
Abel

30

Użyj String#nextjako licznika.

>> n = "000"
>> 3.times { puts "file_#{n.next!}" }
file_001
file_002
file_003

next jest stosunkowo „sprytny”, co oznacza, że ​​możesz nawet wybrać

>> n = "file_000"
>> 3.times { puts n.next! }
file_001
file_002
file_003

Dzięki za zwrócenie na to uwagi. To taka niesamowita metoda.
Weston Ganger

9

Jak stwierdzono w innych odpowiedziach, "%03d" % numberdziała całkiem dobrze, ale jest sprzeczne z przewodnikiem po stylu ruby :

Preferuj użycie sprintf i jego formatu aliasu zamiast dość tajemniczej metody String #%

Możemy uzyskać ten sam wynik w bardziej czytelny sposób, używając:

format('%03d', number)

1
Jeśli Twoim celem jest nauczenie się niejasnej funkcji języka Ruby, użyj aliasu format. Jeśli Twoim celem jest ułatwienie zrozumienia kodu, powinieneś go użyć sprintf, ponieważ jest on częścią standardowej biblioteki C. Ta nazwa jest używana w różnych językach programowania. O wiele więcej ludzi rozumie, co sprintfrobi, w porównaniu do liczby, która wie, że formatto alias. To, że coś jest częścią RuboCop, nie powoduje, że jest z natury dobre lub złe. Wybierz reguły, które najlepiej pasują do twojego projektu. '%03d' % numberjest jeszcze łatwiejszy do odczytania.
Tilo,

1
Przeszedłem przez tę samą pętlę, zmieniając "%02d" % numna sprintf(...), a następnie format(...)według sugestii RuboCop. Uznałem wtedy, że jest sprintfto bardziej konwencjonalne niż format, dlatego zaktualizowałem rubocop.yml Style/FormatString: EnforcedStyle: sprintfi teraz dobrze śpię w nocy.
David Hempy

1

filenames = '000'.upto('100').map { |index| "file_#{index}" }

Wyjścia

[file_000, file_001, file_002, file_003, ..., file_098, file_099, file_100]

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.