4

I'm trying to iterate through an array of strings and replace the words if they match any of the substitution rules:

array= ["I love chicken!", "I love lamb!", "I love beef!"]
substitutions = {
"love" => "hate",
"lamb" => "turkey"
}

I want to iterate through the array and check for any words that match with the keys within the substitutions hash. The array would then become:

array= ["I hate chicken!", "I hate turkey!", "I hate beef!"]

This is what I have so far:

array.each do |strings|
strings = strings.split
    strings.each do |word|
        substitutions.each do |phrase,substitute|
            if word == phrase
                word = substitute
                return word
            end
        end
    end
end

3 Answers 3

2

This will give you the result you need. As you may see, you are overcomplicating a bit

arry= ["I love chicken!", "I love lamb!", "I love beef!"]
substitutions = { "love" => "hate", "lamb" => "turkey" }

arry.each_with_index do |str,ind|
  substitutions.each_key do |word|
    arry[ind].gsub!(word,substitutions[word]) if str.include?(word)
  end
end

puts arry

This will give you:

[ "I hate chicken!", "I hate turkey!", "I hate beef!" ]

Your strategy of spliting the sentences wouldn't work. The exclamation marks would create some trouble. The idea of testing with #include? is much better in this case.

And notice the use of gsub! (with the !), which will make the changes in the original array.

1
  • 1
    No need to define the keys-array words. Iterate over the substitutions hash with Hash#each_key Commented Dec 9, 2016 at 0:02
1
arr  = ["I love chicken!", "I love lamb!", "I love beef!"]
subs = { "love"=>"hate", "lamb"=>"turkey" }

subs.default_proc = ->(h,k) { k }
  #=> #<Proc:0x007f9ff0a014b8@(irb):1343 (lambda)>
arr.map { |s| s.gsub(/\w+/, subs) }
  #=> ["I hate chicken!", "I hate turkey!", "I hate beef!"]

I used Hash#default_proc= to attach a proc to subs so that subs[k] returns k if subs does not have a key k and used the form of String#gsub that employs a hash for making substitutions.

0

It's not necessary to iterate over the hash at all. Instead use it to generate a regular expression and pass it to gsub. Here's how I've done it many times; It's the basis for a templating engine:

array = ["I love chicken!", "I love lamb!", "I love beef!"]
substitutions = {
  "love" => "hate",
  "lamb" => "turkey"
}

key_regex = /\b(?:#{Regexp.union(substitutions.keys).source})\b/
# => /\b(?:love|lamb)\b/

array.map! { |s|
  s.gsub(key_regex, substitutions)
}

array # => ["I hate chicken!", "I hate turkey!", "I hate beef!"]

If you don't want to munge the contents of array use map instead, which will return a new array leaving the original untouched:

array.map { |s|
  s.gsub(key_regex, substitutions)
}
# => ["I hate chicken!", "I hate turkey!", "I hate beef!"]

array # => ["I love chicken!", "I love lamb!", "I love beef!"]

The trick is defining the regular expression used to find the key words.

See "How to build a case-insensitive regular expression with Regexp.union" along with the gsub documenation for more information.

0

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.