15

I have a hash collection: my_hash = {"1" => "apple", "2" => "bee", "3" => "cat"}

What syntax would I use to replace the first occurrence of the key with hash collection value in a string?

eg my input string: str = I want a 3

The resulting string would be: str = I want a cat

4
  • 2
    What assumptions are there about the input string? Generally, template languages like this mark it in some way, like str = I want a {3} (.NET string formatting). Commented Apr 9, 2012 at 22:32
  • 2
    Stack Overflow is not "please code this for me"; what is your code so far? What are your questions? Commented Apr 9, 2012 at 22:32
  • ...apparently I'm wrong. As evidenced below, apparently we are all so desperate to help that we hand out code to new users. Welcome to Stack Overflow! ;) Commented Apr 9, 2012 at 22:41
  • 1
    I would use Ruby 2.0's built in string templating feature if at all possible. Given a hash with symbol keys, h = {pet: "cat"} you can do this: "I want a %{pet}" % h #=> "I want a cat" Commented Jun 10, 2014 at 21:09

8 Answers 8

21

My one liner:

hash.each { |k, v| str[k] &&= v }

or using String#sub! method:

hash.each { |k, v| str.sub!(k, v) }
Sign up to request clarification or add additional context in comments.

4 Comments

+1 (when I get the votes) for the useage of String#[]= and &&=.
Can some one explain what the first one liner does?
As boolean operators in Ruby are short-circuited the second argument is evaluated if and only if the first one is true. The String#[] if has given string it find it and return sub-string reference to it. So if we assign something to it we will change given part of the string. Finally we join it together and if sub-string is found in string then substitute it with hash value.
Lukasz, nice work. One correction: you need to use the 'sub!' method rather than the 'sub' method in order for your second example to work. 'sub!' alters the string in place. (Or use 'gsub!' to replace all occurrences of the match in the string.)
17
"I want a %{b}" % {c: "apple", b: "bee", a: "cat"}
=> "I want a bee"

Comments

4

Assuming Ruby 1.9 or later:

str.gsub /\d/, my_hash

Comments

3

I didn't understand your problem, but you can try this:

my_hash = {"1" => "apple", "2" => "bee", "3" => "cat"}
str = "I want a 3"
str.gsub(/[[:word:]]+/).each do |word|
  my_hash[word] || word
end
#=> "I want a cat"

:D

2 Comments

IMHO it's a little bit overloaded.
Heh, I like this one for turning my head upside down. (I'd +1 you, but I'm out for the day. ;)
3

Just to add point free style abuse to fl00r's answer:

my_hash = {"1" => "apple", "2" => "bee", "3" => "cat"}
my_hash.default_proc = Proc.new {|hash, key| key}
str = "I want a 3"
str.gsub(/[[:word:]]+/).each(&my_hash.method(:[]))

Comments

2
my_hash = {"1" => "apple", "2" => "bee", "3" => "cat"}
str = "I want a 3"

If there isn't any general pattern for the strings you want to substitute, you can use:

str.sub /#{my_hash.keys.map { |s| Regexp.escape s }.join '|'}/, my_hash

But if there is one, the code becomes much simpler, e.g.:

str.sub /[0-9]+/, my_hash

If you want to substitute all the occurrences, not only the first one, use gsub.

Comments

0

You can use String.sub in ruby 1.9:

string.sub(key, hash[key])

1 Comment

@Oleksi You meant hash not hash[key] i.e. my_hash = {"1" => "apple", "2" => "bee", "3" => "cat"} my_str = 'I want a 3' puts my_str.sub('3', my_hash) # => 'I want a cat'
0

The following code replace the first occurrence of the key with hash collection value in the given string str

 str.gsub(/\w+/) { |m| my_hash.fetch(m,m)}
    => "I want a cat"

2 Comments

It would improve the quality of your answer if you could provide more of an explanation of what your code does. Why should someone try your code, is there something which can help them understand what they need to do?
explanation added

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.