iteracja po każdym znaku String w Rubim 1.8.6 (each_char)

86

Jestem nowym użytkownikiem języka Ruby i obecnie próbuję operować na każdym znaku oddzielnie od podstawowego ciągu znaków w języku Ruby. Używam Ruby 1.8.6 i chciałbym zrobić coś takiego:

"ABCDEFG".each_char do |i|
  puts i
end

Powoduje to niezdefiniowany błąd metody „each_char”.

Spodziewałem się zobaczyć pionowy wynik:

A
B
C
D
..etc

Czy each_charmetoda jest zdefiniowana tylko dla 1,9? Próbowałem użyć zwykłej eachmetody, ale blok po prostu umieszcza cały ciąg w jednej linii. Jedynym sposobem, w jaki mogę to zrobić, co jest raczej niewygodne, jest utworzenie od samego początku tablicy znaków:

['A','B','C','D','...'].each do|i|
  puts i
end

Wyprowadza żądane:

A
B
C
..etc

Czy jest może sposób na uzyskanie tego wyniku przy użyciu niezmodyfikowanego ciągu?

Myślę, że odpowiednik Javy to:

for (int i = 0; i < aString.length(); i++){
  char currentChar = aString.charAt(i);
  System.out.println(currentChar);
}
denchr
źródło
1
„asfds” .char.each ....
Muhammad Umer

Odpowiedzi:

115

Mam ten sam problem. Zwykle uciekam się do String#split:

"ABCDEFG".split("").each do |i|
  puts i
end

Myślę, że możesz też zaimplementować to samodzielnie w ten sposób:

class String
  def each_char
    self.split("").each { |i| yield i }
  end
end

Edycja: jeszcze inna alternatywa String#each_byte, dostępna w Ruby 1.8.6, zwraca wartość ASCII każdego znaku w łańcuchu ASCII:

"ABCDEFG".each_byte do |i|
  puts i.chr # Fixnum#chr converts any number to the ASCII char it represents
end
Jeremy Ruten
źródło
Dzięki za pomocną wskazówkę. To działa dobrze. Więc do czego służy metoda each_char? Przypuszczam, że tylko dla nowszej wersji?
denchr
Do tej pory nie sprawdzałem tego, ale po trochę googlowaniu, najwyraźniej jest omyłkowo wymieniony w dokumentacji 1.8.6, ale nie jest dostępny do 1.8.7.
Jeremy Ruten
Metoda each_char jest przeznaczona dla starszej wersji, która w innym przypadku jej nie ma. Jeszcze nieudokumentowane na ruby-doc.org/core/classes/String.html#M000862 i ku mojemu zdziwieniu widzę, że each_char daje ciąg, jak podział Jeremy'ego.
Martin Dorey
15

Rozszerzenie komentarza la_f0ka, zwł. jeśli potrzebujesz również pozycji indeksu w swoim kodzie, powinieneś być w stanie to zrobić

s = 'ABCDEFG'
for pos in 0...s.length
    puts s[pos].chr
end

Jest .chrto ważne, ponieważ Ruby <1,9 zwraca kod znaku na tej pozycji zamiast podłańcucha jednego znaku na tej pozycji .

sschuberth
źródło
5
0..s.length - 1=0...s.length
MatthewRock
Dzięki @MatthewRock, zmieniony.
sschuberth
1

w 1.8.6 jest naprawdę problem. i po tej edycji jest ok

w 1.8.6 możesz dodać to:

requre 'jcode'
kaka2008
źródło
1

Ale teraz możesz zrobić znacznie więcej:

a = "cruel world"

a.scan(/\w+/)        #=> ["cruel", "world"]

a.scan(/.../)        #=> ["cru", "el ", "wor"]

a.scan(/(...)/)      #=> [["cru"], ["el "], ["wor"]]

a.scan(/(..)(..)/)   #=> [["cr", "ue"], ["l ", "wo"]]
GB
źródło
1
"ABCDEFG".chars.each do |char|
  puts char
end

również

"ABCDEFG".each_char {|char| p char}

Wersja Ruby> 2.5.1

juliański
źródło