iterando sobre cada caractere de uma String no ruby ​​1.8.6 (each_char)

86

Eu sou novo no Ruby e atualmente estou tentando operar cada caractere separadamente de uma String base no Ruby. Estou usando o Ruby 1.8.6 e gostaria de fazer algo como:

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

Isso produz um erro de método indefinido `each_char '.

Eu esperava ver uma saída vertical de:

A
B
C
D
..etc

O each_charmétodo está definido apenas para 1.9? Tentei usar o eachmétodo simples , mas o bloco simplesmente produz a string inteira em uma linha. A única maneira de descobrir como fazer isso, o que é bastante inconveniente, é criar uma série de personagens desde o início:

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

Isso resulta no desejado:

A
B
C
..etc

Existe talvez uma maneira de obter essa saída usando uma string não modificada para começar?

Acho que o equivalente em Java é:

for (int i = 0; i < aString.length(); i++){
  char currentChar = aString.charAt(i);
  System.out.println(currentChar);
}
denchr
fonte
1
"asfds" .char.each ....
Muhammad Umer

Respostas:

115

Eu tenho o mesmo problema. Eu costumo recorrer a String#split:

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

Eu acho que você também pode implementá-lo desta forma:

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

Editar: ainda outra alternativa está String#each_bytedisponível em Ruby 1.8.6, que retorna o valor ASCII de cada caractere em uma string ASCII:

"ABCDEFG".each_byte do |i|
  puts i.chr # Fixnum#chr converts any number to the ASCII char it represents
end
Jeremy Ruten
fonte
Obrigado pela dica útil. Funciona bem. Então, para que é usado o método each_char? Suponho que apenas para a versão mais recente?
denchr
Eu não olhei para ele até agora, mas depois de pesquisar um pouco no Google, aparentemente ele está listado por engano na documentação do 1.8.6, mas não está disponível até 1.8.7.
Jeremy Ruten
O método each_char é para a versão mais antiga, que de outra forma não o tem. Ainda não documentado em ruby-doc.org/core/classes/String.html#M000862 e para minha surpresa, vejo que each_char produz uma string, como a divisão de Jeremy.
Martin Dorey
15

Estendendo o comentário de la_f0ka, esp. se você também precisa da posição do índice em seu código, você deve ser capaz de fazer

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

O .chré importante porque Ruby <1.9 retorna o código do caractere naquela posição em vez de uma substring de um caractere naquela posição .

sschuberth
fonte
5
0..s.length - 1=0...s.length
MatthewRock 01 de
Obrigado @MatthewRock, mudou.
sschuberth
1

realmente há um problema em 1.8.6. e está tudo bem após esta edição

em 1.8.6, você pode adicionar este:

requre 'jcode'
kaka2008
fonte
1

Mas agora você pode fazer muito mais:

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
fonte
1
"ABCDEFG".chars.each do |char|
  puts char
end

Além disso

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

Versão Ruby> 2.5.1

Julian
fonte