Ответ 1
Прокомментировать достоинство предложенной меры потребует спекуляции, которая является вне границ в SO. Поэтому я просто продемонстрирую, как вы можете реализовать свой предлагаемый подход.
код
Сначала определите вспомогательный метод:
class Array
def difference(other)
h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
reject { |e| h[e] > 0 && h[e] -= 1 }
end
end
Короче говоря, если
a = [3,1,2,3,4,3,2,2,4]
b = [2,3,4,4,3,4]
затем
a - b #=> [1]
тогда
a.difference(b) #=> [1, 3, 2, 2]
Этот метод разработан в моем ответе на этот вопрос SO. Я нашел так много применений, что я предложил добавить его в Ruby Core.
Следующий метод создает хеш, ключи которого являются элементами names
(строки) и значениями которых являются доли букв в строке target
, которые содержатся в каждой строке в names
.
def target_fractions(names, target)
target_arr = target.downcase.scan(/[a-z]/)
target_size = target_arr.size
names.each_with_object({}) do |s,h|
s_arr = s.downcase.scan(/[a-z]/)
target_remaining = target_arr.difference(s_arr)
h[s] = (target_size-target_remaining.size)/target_size.to_f
end
end
Пример
target = "Jimmy S. Bond"
и имена, которые вы сравниваете, даны
names = ["Jill Dandy", "Boomer Asad", "Josefine Simbad"]
затем
target_fractions(names, target)
#=> {"Jill Dandy"=>0.5, "Boomer Asad"=>0.5, "Josefine Simbad"=>0.8}
Объяснение
Для приведенных выше значений names
и target
,
target_arr = target.downcase.scan(/[a-z]/)
#=> ["j", "i", "m", "m", "y", "s", "b", "o", "n", "d"]
target_size = target_arr.size
#=> 10
Теперь рассмотрим
s = "Jill Dandy"
h = {}
затем
s_arr = s.downcase.scan(/[a-z]/)
#=> ["j", "i", "l", "l", "d", "a", "n", "d", "y"]
target_remaining = target_arr.difference(s_arr)
#=> ["m", "m", "s", "b", "o"]
h[s] = (target_size-target_remaining.size)/target_size.to_f
#=> (10-5)/10.0 => 0.5
h #=> {"Jill Dandy"=>0.5}
Расчеты аналогичны для Бумера и Жозефина.