web-dev-qa-db-fra.com

itérer sur chaque caractère d'une chaîne dans Ruby 1.8.6 (each_char)

Je suis nouveau sur Ruby et j'essaie actuellement de manipuler chaque caractère séparément d'une chaîne de base en Ruby. J'utilise Ruby 1.8.6 et j'aimerais faire quelque chose comme:

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

Ceci produit une erreur de méthode eachde_char non définie.

Je m'attendais à voir une sortie verticale de:

A
B
C
D
..etc

Est le each_char méthode définie uniquement pour 1.9? J'ai essayé d'utiliser la méthode plain each, mais le bloc affiche simplement la chaîne entière sur une ligne. La seule façon de faire cela, ce qui est plutôt gênant, est de créer un tableau de caractères depuis le début:

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

Cette sortie le souhaité:

A
B
C
..etc

Y at-il peut-être un moyen d'obtenir cette sortie en utilisant une chaîne non modifiée pour commencer?

Je pense que l'équivalent Java est:

for (int i = 0; i < aString.length(); i++){
  char currentChar = aString.charAt(i);
  System.out.println(currentChar);
}
83
denchr

J'ai le même problème. Je recourt habituellement à String#split:

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

Je suppose que vous pourriez aussi l'implémenter vous-même comme ceci:

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

Edit: Encore une autre alternative est String#each_byte, Disponible dans Ruby 1.8.6, qui renvoie la valeur ASCII de chaque caractère dans un ASCII chaîne:

"ABCDEFG".each_byte do |i|
  puts i.chr # Fixnum#chr converts any number to the ASCII char it represents
end
110
Jeremy Ruten

Extension du commentaire de la_f0ka, en particulier si vous avez également besoin de la position d'index dans votre code, vous devriez pouvoir faire

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

Le .chr est important car Ruby <1.9 renvoie le code du caractère à cette position au lieu de ne sous-chaîne d’un caractère à cette position .

14
sschuberth

il y a vraiment un problème en 1.8.6. et c'est ok après cette édition

en 1.8.6, vous pouvez ajouter ceci:

requre 'jcode'
1
kaka2008

Mais maintenant, vous pouvez faire beaucoup plus:

a = "cruel world"

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

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

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

a.scan(/(..)(..)/)   #=> [["cr", "ue"], ["l ", "wo"]]
1
G.B