Sabbu
Sabbu

Reputation: 179

Check the string with hash key

I am using Ruby 1.9.

I have a hash:

Hash_List={"ruby"=>"fun to learn","the rails"=>"It is a framework"}

I have a string like this:

test_string="I am learning the ruby by myself and also the rails."

I need to check if test_string contains words that match the keys of Hash_List. And if it does, replace the words with the matching hash value.

I used this code to check, but it is returning them empty:

another_hash=Hash_List.select{|key,value| key.include? test_string}

Upvotes: 0

Views: 1267

Answers (3)

EugZol
EugZol

Reputation: 6545

First, follow naming conventions. Variables are snake_case, and names of classes are CamelCase.

hash = {"ruby" => "fun to learn", "rails" => "It is a framework"}
words = test_string.split(' ') # => ["I", "am", "learning", ...]
another_hash = hash.select{|key,value| words.include?(key)}

Answering your question: split your test string in words with #split and then check whether words include a key.

For checking if the string is substring of another string use String#[String] method:

another_hash = hash.select{|key, value| test_string[key]}

Upvotes: 0

the Tin Man
the Tin Man

Reputation: 160551

OK, hold onto your hat:

HASH_LIST = {
  "ruby" => "fun to learn",
  "the rails" => "It is a framework"
}

test_string = "I am learning the ruby by myself and also the rails."

keys_regex = /\b (?:#{Regexp.union(HASH_LIST.keys).source}) \b/x # => /\b (?:ruby|the\ rails) \b/x
test_string.gsub(keys_regex, HASH_LIST) # => "I am learning the fun to learn by myself and also It is a framework."

Ruby's got some great tricks up its sleeve, one of which is how we can throw a regular expression and a hash at gsub, and it'll search for every match of the regular expression, look up the matching "hits" as keys in the hash, and substitute the values back into the string:

gsub(pattern, hash) → new_str

...If the second argument is a Hash, and the matched text is one of its keys, the corresponding value is the replacement string....

Regexp.union(HASH_LIST.keys) # => /ruby|the\ rails/
Regexp.union(HASH_LIST.keys).source # => "ruby|the\\ rails"

Note that the first returns a regular expression and the second returns a string. This is important when we embed them into another regular expression:

/#{Regexp.union(HASH_LIST.keys)}/ # => /(?-mix:ruby|the\ rails)/
/#{Regexp.union(HASH_LIST.keys).source}/ # => /ruby|the\ rails/

The first can quietly destroy what you think is a simple search, because of the ?-mix: flags, which ends up embedding different flags inside the pattern.

The Regexp documentation covers all this well.

This capability is the core to making an extremely high-speed templating routine in Ruby.

Upvotes: 1

Cary Swoveland
Cary Swoveland

Reputation: 110685

You could do that as follows:

Hash_List.each_with_object(test_string.dup) { |(k,v),s| s.sub!(/#{k}/, v) } 
 #=> "I am learning the fun to learn by myself and also It is a framework."

Upvotes: 0

Related Questions