Ruby: Jak uzyskać pierwszy znak łańcucha

113

Jak uzyskać pierwszy znak w ciągu za pomocą Rubiego?

Ostatecznie to, co robię, to wzięcie czyjegoś nazwiska i utworzenie z niego inicjału.

Więc jeśli ciągiem jest „Smith”, chcę tylko „S”.

Shpigford
źródło
10
Na marginesie, jeśli jesteś w Railsach, możesz po prostu to zrobić'Smith'.first
Walking Wiki
Ruby 1.9+ ma"Smith".chr #=> "S"
Tyler James Young

Odpowiedzi:

128

Możesz użyć otwartych klas Rubiego, aby uczynić swój kod bardziej czytelnym. Na przykład to:

class String
  def initial
    self[0,1]
  end
end

pozwoli ci użyć initialmetody na dowolnym łańcuchu. Więc jeśli masz następujące zmienne:

last_name = "Smith"
first_name = "John"

Wtedy możesz uzyskać bardzo wyraźne i czytelne inicjały:

puts first_name.initial   # prints J
puts last_name.initial    # prints S

Druga wspomniana tutaj metoda nie działa w Ruby 1.8 (nie żebyś i tak już używał 1.8! - ale kiedy opublikowano tę odpowiedź, była nadal dość powszechna):

puts 'Smith'[0]           # prints 83

Oczywiście, jeśli nie robisz tego regularnie, zdefiniowanie metody może być przesadą i możesz to zrobić bezpośrednio:

puts last_name[0,1] 
ikonoklasta
źródło
101

Jeśli używasz najnowszej wersji Rubiego (1.9.0 lub nowszej), powinny działać następujące elementy:

'Smith'[0] # => 'S'

Jeśli używasz wersji 1.9.0+ lub 1.8.7, poniższe powinny działać:

'Smith'.chars.first # => 'S'

Jeśli używasz wersji starszej niż 1.8.7, powinno to działać:

'Smith'.split(//).first # => 'S'

Zauważ, że 'Smith'[0,1]nie nie działa na 1.8, to będzie nie daje pierwszy znak, to tylko daje pierwszy bajt .

Jörg W Mittag
źródło
1
zauważ, że działa to tylko w ruby19. w ruby18 "Smith"[0]zwróci wartość całkowitą znaku „S”. Obie wersje są posłuszne "Smith"[0,1] == "S".
rampion
@rampion: Jasne, ale w pytaniu nic nie wskazuje na to, że OP nie używa najnowszej wersji, więc po co komplikować sprawy?
Jörg W Mittag
4
Ruby 1.8 nie jest dziedzictwem! Linia Ruby 1.8 jest nadal obsługiwana i najprawdopodobniej zostanie wydana wersja 1.8.8. Co więcej, ani JRuby, ani Rubinius nie obsługują jeszcze 1.9. Postawiłbym 5 $, że jest dziś znacznie więcej użytkowników 1,8 niż 1,9.
Marc-André Lafortune
3
@ Jörg: Odpowiedź "Smith"[0,1]działa na 1.8 (zakładając ASCII). Nie jestem pewien, dlaczego zakładasz tak wiele o żądającym, a także o wszystkich innych, którzy chcieliby się czegoś nauczyć z tego pytania. Na przykład Mac OS X jest dostarczany w pakiecie z Ruby 1.8, więc nie jest wymagana instalacja dla tych użytkowników.
Marc-André Lafortune
3
Jak uzyskać inicjał nazwy „Ångström” (w UTF-8), aby działał zgodnie z oczekiwaniami zarówno w Rubim 1.8.x, jak i 1.9.x? Żadna z sugerowanych metod nie zadziała w 1.8.x.
Lars Haugseth
30
"Smith"[0..0]

działa zarówno w Ruby 1.8 jak i Ruby 1.9.

Andrew Grimm
źródło
1
To najlepsze rozwiązanie, jeśli wymagana jest obsługa wersji 1.8.6 i 1.9.
plang
14

W MRI 1.8.7 lub nowszym:

'foobarbaz'.each_char.first
Wayne Conrad
źródło
12

W Railsach

name = 'Smith'
name.first 
Suganya
źródło
łatwy sposób użycia. Dziękuję za odpowiedź.
AMIC MING
12

Spróbuj tego:

>> a = "Smith"
>> a[0]
=> "S"

LUB

>> "Smith".chr
#=> "S"
Gagan Gami
źródło
5
>> s = 'Smith'                                                          
=> "Smith"                                                              
>> s[0]                                                                 
=> "S"                                                        
SilentGhost
źródło
1
zauważ, że działa to tylko w ruby19. w ruby18 "Smith"[0]zwróci wartość całkowitą znaku „S”. Obie wersje są posłuszne "Smith"[0,1] == "S".
rampion
1
@rampion: rzeczywiście. Dodam, że "Smith"[0] == ?Sto prawda na Ruby 1.8 i 1.9
Marc-André Lafortune
2

Z powodu irytującego wyboru projektu w Rubim przed wersją 1.9 - some_string[0]zwraca kod pierwszego znaku - najbardziej przenośnym sposobem zapisania tego jest some_string[0,1]polecenie pobrania podciągu o indeksie 0 o długości 1 znaku.

Głaskanie pod brodę
źródło
str [0,1] również nie działa tak samo w 1.8 i 1.9, ponieważ w pierwszym zwraca pierwszy bajt , aw drugim zwraca pierwszy znak .
Lars Haugseth
1
To nie jest tak naprawdę różnica w działaniu indeksowania, tak jak w przypadku obsługi języków wielobajtowych w wersji 1.9. Oba mają na celu zwrócenie pierwszej postaci, ale 1.8 ma bardziej naiwny pogląd na to, czym jest „postać”.
Chuck
2

Inna opcja, o której jeszcze nie wspomniano:

> "Smith".slice(0)
#=> "S"
jeffdill2
źródło
0

Możesz także użyć truncate

> 'Smith'.truncate(1, omission: '')
#=> "S"

lub do dodatkowego formatowania:

> 'Smith'.truncate(4)
#=> "S..."

> 'Smith'.truncate(2, omission: '.')
#=> "S."
Eric Norcross
źródło
-1

Każda z tych metod będzie działać:

name = 'Smith'
puts name.[0..0] # => S
puts name.[0] # => S
puts name.[0,1] # => S
puts name.[0].chr # => S
Saranki Magenthirarajah
źródło
1
Żadna z tych metod nie zadziała .później name. A ostatnia nie jest sensowna, nawet jeśli usuniesz ., ponieważ używa dwóch różnych metod do zrobienia tego samego - [0] i chr() .
jeffdill2