Jamie Macey
11/27/2006 4:41:00 AM
Well, I'm not sure I can add anything not covered by Adam's solution
(forwarded in by James), but here goes.
I started with the naive solution:
class DictionaryMatcher < Array
def =~(string)
self.map{|e| Regexp.new(e) =~ string }.compact.min
end
end
I then fleshed it out with a case insensitive option, and more tests.
- Jamie
class DictionaryMatcher < Array
alias_method :===, :=~
alias_method :match, :=~
def initialize(default = [], options = nil)
super(default)
unless options.nil? or options.is_a? Fixnum
options = Regexp::IGNORECASE
end
@regexp_options = options
end
def =~(string)
self.map{|e| Regexp.new(e, @regexp_options) =~ string }.compact.min
end
end
class DictionaryMatcherTest < Test::Unit::TestCase
def test_acceptance
# creates a new empty matcher
dm=DictionaryMatcher.new
# adds strings to the matcher
dm << "string"
dm << "Ruby"
# determines whether a given word was one of those added to the matcher
assert_equal true, dm.include?("Ruby") # => true
assert_equal false, dm.include?("missing") # => false
assert_equal false, dm.include?("stringing you along") # => false
# Regexp-like substing search
assert_equal 5, dm =~ "long string" # => 5
assert_equal nil, dm =~ "rub you the wrong way" # => nil
# will automatically work as a result of implementing
# DictionaryMatcher#=~ (see String#=~)
assert_equal 5, "long string" =~ dm # => true
end
def test_include_eh
dm = DictionaryMatcher.new(['string', 'ruby', 'foo'])
assert_equal true, dm.include?('string' )
assert_equal true, dm.include?('ruby' )
assert_equal true, dm.include?('foo' )
assert_equal false, dm.include?('stringa')
assert_equal false, dm.include?('astring')
end
def test_equals_tilde
dm = DictionaryMatcher.new(['string', 'ruby', 'foo'])
assert_equal 0, dm =~ 'string'
assert_equal 0, dm =~ 'string two'
assert_equal 6, dm =~ 'three string'
assert_equal 5, dm =~ 'four string five'
assert_equal nil, dm =~ 'strng'
assert_equal 0, 'string' =~ dm
assert_equal 2, 'a string b' =~ dm
assert_equal nil, 'strng' =~ dm
end
def test_case_sensitivity
dm = DictionaryMatcher.new(['Foo','bar'])
assert_equal 0, dm =~ 'Foo'
assert_equal 0, dm =~ 'bar'
assert_equal nil, dm =~ 'foo'
assert_equal nil, dm =~ 'Bar'
end
def test_case_insensitivity
dm = DictionaryMatcher.new(['Foo','bar'], true)
assert_equal 0, dm =~ 'Foo'
assert_equal 0, dm =~ 'bar'
assert_equal 0, dm =~ 'foo'
assert_equal 0, dm =~ 'Bar'
end
def test_greediness
dm = DictionaryMatcher.new(['hi','child'])
r = /hi|child/
assert_equal r =~ 'children', dm =~ 'children'
dm = DictionaryMatcher.new(['child','hi'])
r = /child|hi/
assert_equal r =~ 'children', dm =~ 'children'
end
end