0

如何改进这种排序方法以满足以下条件:

  • 首先返回完全匹配
  • 部分匹配遵循完全匹配
def find_me
  records = ["gogol", "garrison", "feathers", "grains"]
  sorted = []   

  print "what are you looking for? "
  term = gets.chomp.downcase    

  records.select do |record|
    if term == record.downcase
      #exact match
      sorted << record
    elsif  term[0] == record[0] or term[1] == record[1] or term[2] == record[2]
      #if the first three chars match add it
      sorted << record
    end
  end

  sorted.sort! {|b| term <=> b }
end
4

2 回答 2

2
def find_me
  records = ["gogol", "garrison", "feathers", "grains"]
  exact_matches   = []
  partial_matches = []  

  print "what are you looking for? "
  term = gets.chomp.downcase    

  records.each do |record|
    if term == record.downcase
      #exact match
      exact_matches << record
    elsif  term.slice(0, 3) == record.slice(0, 3)
      #if the first three chars match add it
      partial_matches << record
    end
  end

  # Just add the Arrays and it'll put the exact matches first and the 
  # partial ones last without a need for sorting. =)
  sorted = exact_matches + partial_matches 
end
于 2012-05-09T18:06:33.097 回答
1

您可以记下哪些是完全匹配的,哪些是完全匹配的:

matches = records.each_with_object([]) do |record, m|
  if term == record.downcase
    m << [ 0, record ]
  elsif term[0, 3] == record[0, 3]
    m << [ 1, record ]
  end
end

然后对两个值进行排序并解压缩内部数组:

matches.sort.map(&:last)

我不确定您期望这种方式做什么:

sorted.sort! {|b| term <=> b }

但它会做一些奇怪的事情,因为该sort块应该将数组的两个元素相互比较,而您完全忽略了第二个;例如,这发生在我身上:

>> [4,2,1,2,4].sort { |x| 3 <=> x }
=> [4, 4, 1, 2, 2]

并且由此产生的排序没有多大意义。


正在同时each_with_object做几件事:

  1. 找到完全匹配并将它们标记为完全匹配(前导 0)。
  2. 找到前缀匹配并将它们标记为部分匹配(前导 1)。
  3. 返回要存储的组合列表matchese.each_with_object(m)m块作为其第二个参数并返回m

这会给你留下一个matches看起来像这样的:

[ [0, a], [1, b], [1, c], ... ]

前导 0 表示完全匹配,1 表示前缀匹配。然后你可以让sort排序matches正常,因为Array#<=>逐个元素比较数组;0 在 1 之前,因此完全匹配最终排在第一位。然后我们可以丢弃使用map调用last每个内部数组的精确/部分指标。

于 2012-05-09T18:03:54.140 回答