tags:

views:

59

answers:

3

I'm trying to search a string for match on an array of words. I tested the code by specifying a word and also an input and it correctly finds it, but for some reason I can't get it to work in general. I checked that the input is a String and the words are extracted from the list as well. Any help on this would be appreciated. Thanks.

def self.wordmatch(input, list)
  list.each {|word|
  if (input =~ /#{word}/i)
    puts "#{input} => #{word}"
    return 'MATCH'
  end
  }
end
A: 

Try this. I think you have them backwards..


def self.wordmatch(input, list)
  list.each {|word|
  if (word =~ /#{input}/i)
    puts "#{input} => #{word}"
    return 'MATCH'
  end
  }
end

http://rubular.com/ is a great site to mess with this stuff.

Mark Redding
Mark, I tried this and the end result is still the same. You mentioned that it won't work for "list of strings". Could you explain why?
Brags Kadakia
I read your question such that I thought input="love" , list = ["i love summer", "summer of love", "i hate summer"]
Mark Redding
+1  A: 

This seems to work OK. What you may be getting confused by is that if there is no match then ruby will return the last evaluated expression, which in this case is the list.

I'm not sure what you are wanting to return here in the case of a failure but this will return true/false

 def self.wordmatch(input, list)
  list.each {|word|
  if (word =~ /#{input}/i)
    puts "#{input} => #{word}"
    return true
  end
  }
  return false
end

The following test code

words = %w[a b c]
matches = %w[a b c d]

matches.each do |match|
    puts "Testing #{match} = #{wordmatch(match, words)}"
end

Produces the following results

Testing a = true
Testing b = true
Testing c = true
Testing d = false

EDIT

Following on from the comments this seems to work exactly as advertised.

def wordmatch(input, list)
  list.each {|word|
  if (input =~ /#{word}/i)
    puts "#{input} => #{word}"
    return 'MATCH'
  end
  }
  return nil
end

list = ["hate", "indifference", "love", "foo"]
input1 = "I love summer"
input2 = "I endure summer"

puts "Testing #{input1} = #{wordmatch(input1, list)}"
puts "Testing #{input2} = #{wordmatch(input2, list)}"

And produces the following results

I love summer => love
Testing I love summer = MATCH
Testing I endure summer = 
Steve Weet
This won't work if words is a "list of strings" as mentioned in the question.
Mark Redding
Thanks for your answer. Here is the intended behavior: input = "I love summer", list = ["hate", "indifference", "love", "foo"]. Now calling wordmatch(input, list) should put the matching word in the console and return "MATCH". For some reason I'm not able to get this to work, seems simple enough.
Brags Kadakia
@Mark Redding. Why not? That is exactly what this is doing passing a list of single character strings
Steve Weet
@Steve Weet, sorry bout that. Question seems like it could have used a bit more info.
Mark Redding
A: 

I would implement it like this:

def wordmatch(input, list)
  found = input.scan(/\w+/).find {|w| list.include?(w)}
  if found
    puts found
    return "MATCH"
  end
end

It transform your input string to an array of words, and runs Array#find on it to find the first word in the array that is included in the list array.

To make it case insensitive, you might want to add map(&:downcase) before the find if your list contains only lowercase words.

As noted by others, your implementation will return the whole list when a match is not found, since you did not set an explicit return value in that case.

Lars Haugseth