2012-06-08 3 views
1

Мне нужно найти частичное совпадение в инвертированном индексе, следующий код работает для точных совпадений, но не для частичного. Переработал это из примера в http://rosettacode.org/wiki/Inverted_Index (который больше не работает в Ruby1.9.3)Ruby: поиск частичного совпадения в инвертированном индексе

Как это сделать наиболее эффективным способом, пожалуйста? Пожалуйста, не советую использовать Lucene, Sphinx и т. Д., Если вы не знаете легкое, простое и чистое решение Ruby, захотите сделать это сами.

@data = {"contents"=>["1.txt", "2.txt"], "of"=>["1.txt", "2.txt"], "file"=>["1.txt", "2.txt"], "one"=>["1.txt"], "two"=>["2.txt"]} 

def search words 
    result = [] 
    words.each do |word| 
    result << @data[word] if @data[word] #should do a partial match 
    end 
    result 
end 

p search ['of'] #=> [["1.txt", "2.txt"]] 
p search ['one'] #=> [["1.txt"]] 
p search ['on'] #=> []     <<should become [["1.txt"]] 
+0

вы можете легко работать с O (1) алгоритм (во времени) для каждого слова, если вы не заботиться о космосе; просто создайте хэш со всеми подстроками в виде ключей с соответствующим значением. – tokland

ответ

3

Определение search следующим образом:

def search words 
    words.map do |word| 
    matches = @data.keys.select {|key| key.include?(word)} 
    matches.map {|match| @data[match] } 
    end  
end 

p search ['of'] #=> [[["1.txt", "2.txt"]]] 
p search ['one'] #=> [[["1.txt"]]] 
p search ['on'] #=> [[["1.txt", "2.txt"], ["1.txt"]]] - note that "contents" contains "on" 
+0

, вероятно, самый простой способ, но не самый эффективный. Обратите внимание, что 'flat_map' сгладит эти вложенные массивы. – tokland

+0

спасибо Чолетт, это странно, мне пришлось встроить свои массивы в круглые скобки, подобные этому поиску (['of']) иначе ошибка << не может преобразовать String в Integer (TypeError) >> – peter

+0

@tokland, что будет больше эффективный? а также дать ответ? – peter

Смежные вопросы