Selecting key words in a string (that are included in an Array) to change their format in Ruby

Report
Question

Please briefly explain why you feel this question should be reported .

Report Cancel

Select key words in a string to change their format in Ruby
I have a big string (text) and an Array of strings (key_words) as below:

text = 'So in this election, we cannot sit back and hope that everything works out for the best. We cannot afford to be tired or frustrated or cynical. No, hear me. Between now and November, we need to do what we did eight years ago and four years ago…'
key_words = ['frustrated', 'tired', 'hope']

My objective is to print each word in ‘text’ while changing the colour and case of the words that are included in key_words. I’ve been able to do that by doing:

require 'colorize'
text.split(/b/).each do |x|
    if  key_words.include?(x.downcase) ; print '#{x}'.colorize(:red)
    else print '#{x}'  end
end

However, since I don’t want to include many words in key_words I want to make the selection more sensitive going beyond an exact match. Such as if, for example:

key_words = ['frustrat', 'tire', 'hope']  => the algorithm would select both 'Frustration', 'Frustrated' or 'Tiring' and 'Tired' or 'Hope' and 'Hopeful'.

I’ve tried playing with word lengths in both the string and the array as below but it’s seems very inefficient solution and I’m getting very confused with the usage of .any? and .include? methods in this scenario.

key_words = ['frustrated', 'tired', 'hope']
key_words_abb = []
key_words.each { |x| key_words_abb  << x.downcase[0][0..x.length-2]}
text.split(/b/).each do |x|
  if key_words_abb.include?(x.downcase[0][0..x.length-2]);  print '#{x}'.colorize(:red)
  else print x
  end
end

Since I can’t find a specific solution online I would appreciate your help.

solved 0
1 Answer 26 views 0

Answer ( 1 )

    1
    January 11, 2017 at 9:30 pm

    Please briefly explain why you feel this answer should be reported .

    Report Cancel

    It’s worth noting that when doing repeated substitutions on strings, especially longer ones, you’ll want your substitution method to be as efficient as possible. Spinning through an array of things to switch out is painfully expensive, especially as that list grows.

    Here’s a variation on your approach:

    replacement = Regexp.new('b%sb' % [ Regexp.union(key_words) ])
    replaced = text.gsub(replacement) do |s|
      s.colorize(:red)
    end
    
    puts replaced
    

    If you’re using that substitution repeatedly you should persist the Regexp object into a constant. That avoids having to compile it for each string you’re adjusting. If the list changes based on factors hard to predict, leave it like this and produce it dynamically.

    One thing to note about using Ruby is it’s often best to express your code as a series of transformations with output as a final step. Putting things like print in the middle of a loop complicates things unnecessarily. If you want to add an additional step to your loop you have to do a lot of extra work to move that print to a later stage. With the approach here you can just chain on the end and do whatever you want.

    Best answer

Leave an answer

Browse

What is the capital of Egypt ? ( Cairo )

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>