1

I want to replace a character in string when a particular condition is satisfied. So , I went through the API doc of Ruby and found the gsub , gsub! etc for similar purpose. When I implemented that in my program I didn't got any error but din't got the desired output too.

The code which I was trying is this :

name.each_char  { |c|

if name[c] == "a"
    name.sub( name[c] , c )
    puts "matched....   "
end

So , for example , I have a string called huzefa and want to replace all the letters with its index numbers . So , what is the way to do it ? Please explain in detail by giving a simple example.

6
  • what is the reason to downvote ? please explain for clearification . Commented Oct 25, 2015 at 13:15
  • 1
    may be they think its simple to be asked; or the title smells duplication or there may be other reasons. or the first downvote might have triggered/influenced the second downvote. (I didnot downvote though, rather upvoted) Commented Oct 25, 2015 at 13:32
  • @illusionist : thank you for your edit. And yes that may be the reason. Commented Oct 25, 2015 at 13:36
  • Converting each character of a string to the string representation of its index depends only on the length of the string: len = 'huzefa'.size; (0...len).map(&:to_s).join # "012345". The result is the same for every other six-character string. Commented Oct 25, 2015 at 16:26
  • Your suggestion is very proper for the case if my requirement was to convert all . But i just want to map only those char to index which satisfies my particular condition . But , still i got to know something new from your answer . Thank you. :) Commented Oct 25, 2015 at 16:43

3 Answers 3

3

You could pass block to gsub and do whatever you want when match happend.

To do it inplace you could use gsub! method.

name = "Amanda"
new_name = name.gsub("a") do |letter|
  puts "I've met letter: " + letter
  "*"
end
# I've met letter: a
# I've met letter: a
# => "Am*nd*"

If you want to work with indexes, you could do something like this:

new_name = name.chars.map.with_index do |c, i|
  if i.odd?
    "*"
  else
    c
  end
end.join
#=> => "A*a*d*"

Here c and i are passed to the block. c is a character and i is an index.

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you , your second suggestion worked for me. If this is not stupid to ask , how does that end.join works ? . Thanx :)
Good answer. A small suggestion: whenever the characters of a string are to be food for an enumerable, use each_char, rather than chars, to avoid the creation of an unneeded temporary array. On a different subject, you've had those eyeglasses for some time. I'm compelled to tell you that they've fallen out of style.
Suppose you want to return a string that is the same as 'cat' except with the letter "a" capitalized. If you write 'cat'.chars.map { |c| c=='a' ? 'A' : c }.join #=> "cAt", the array arr = 'cat'.chars #=> ["c", "a", "t"] is first constructed, then arr.map { |c| c=='a' ? 'A' : c }.join #=> "cAt" is executed. This works because the class Array includes Enumerable and implements Array#each. (cont...)
By contrast, if you write 'cat'.each_char.map { |c| c=='a' ? 'A' : c }.join #=> "cAt", the first step is to create an enumerator enum = 'cat'.each_char #=> #<Enumerator: "cat":each_char>, then enum.map { |c| c=='a' ? 'A' : c }.join #=> "cAt". This works because enum is an instance of the class Enumerator, which includes Enumerable and implements the method each. (We can see the elements enum will pass to Enumerable#map by converting enum to an array: enum.to_a #=> ["c", "a", "t"].) (cont...)
Think of an enumerator as a rule that acts on its receiver (here a string). Being a rule, it requires less memory than does chars, which creates a temporary array (if the string is more than a few characters anyway). On the other hand, suppose we wanted to return a string that shuffles the letters in "cat". Here we must write "cat".chars.shuffle.join #=> "atc" because shuffle is an instance method of Array. If we tried using each_char we get "cat".each_char.shuffle.join #=> undefined method 'shuffle' for #<Enumerator: "cat":each_char>.
|
3

if name=huzefa and you want to replace 'a' with its index..

name.split(//).map.with_index{|x,y| (x=='a')? y : x}.join

to result in #> "huzef5"

Comments

0

Part of string before index + new char + part of string after index:

a = "hello"

idx = 3

new_char = "z"

a[0..(idx-1)] + new_char + a[(idx+1)..-1]

# => "helzo"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.