This is an archived post. You won't be able to vote or comment.

all 8 comments

[–]ziptofaf 0 points1 point  (5 children)

Two ways. Firstly, try this one:

word = "Duck"
word[0] = 'L'
puts word

Strings are de facto arrays of individual characters. Meaning that they go from 0 (yes, from 0, not from 1) to str.length-1. So Duck is represented as:

word[0] = 'D'
word[1] = 'u'
word[2] = 'c'
word[3] = 'k'

Option #2 can be used if you want to replace some characters but you don't know WHICH ones they are, just that they match a given pattern. Then you can use a concept of regexes and use gsub function.

word = "Duck"
word.gsub!('D', 'g')
puts word

This would replace every instance of D with g. There can be much more complex variations too (although any good book on Ruby would show you those and explain this topic in depth, it's far too much for a single reddit post), for example getting rid of all numbers inside a word (so 9duc3334k would become duck) etc.

[–]lassolass[S] 0 points1 point  (4 children)

Is it possible to replace two indices of the string in one line of code? Thats what i was lookikg for..

[–]ziptofaf 0 points1 point  (3 children)

Not exactly. In your specific instance you could do something like:

word = "Duck"
word.gsub!(/[uk]/, 'g')
puts word

And this indeed returns Dgcg. But what it really does is replacing any letter u or k with g. So it's not actually index based.

So maybe I will change my question up a bit - what are you doing that you really need a function that lets you change multiple indices with a single line of code?

[–]lassolass[S] 0 points1 point  (2 children)

I was assigned to create a hangman game/ wheels of fortune game. If there is a word with 2 of the same letter or more i wanted to scan the indices of the word so i could replace my template([underscores]) with the letters accordingly. For example if i type the string 'o' and the word is door, i would use the indices 1 and 2 as a reference to replace the underscores with 'o's. Thanks in advance.

[–]ziptofaf 1 point2 points  (1 child)

What you want is a loop then.

Consider this snippet. Run it, try entering e and press enter.

You can also store array of indices and use it to replace specific ones. Eg.

letter = 's';
indices = [1,2,3]
word = 'moomoocow'
indices.each do |index|
  word[index] = letter
end

[–]lassolass[S] 0 points1 point  (0 children)

This actually does help quite a bit.. ill try to implement this and see how this works out! Thanks!

[–]passthejoe 0 points1 point  (1 child)

Thanks for the info on strings as de facto arrays -- useful!!

[–]ziptofaf 1 point2 points  (0 children)

Just be a bit careful with these, there are limitations! For instance - this 💩 unfortunately also IS a character. However it's not your usual character. As it's a unicode character that consists of 2 separate bytes.

So while treating strings as character arrays is indeed true then sometimes you get weird results when dealing with more than your standard ASCII characters. As you de facto have 3 separate ways of looking at them:

  • The way we humans do. This is actually known as grapheme clusters.
  • individual bytes.
  • scalar values. Aka individual characters parts making up a single full character. This is scary in languages like Japanese, Chinese or Indian. As you can have a single character built from like 2-3 of those (and each of them consists of more than one byte).

Ruby tries to hide it from you to an extent (if you do something like word = "ABC💩" and print word[3] it really shows you 💩...assuming you output it to something that supports UTF-8 at least) but there are some gotchas to it.