提供以下集合:

 collection = [
  ["Pennsylvania", "Bucks", "Doctor"],
  ["New Jersey", "Essex", "Lawyer"],
  ["New Jersey", "Essex", "Firefighter"],
  ["Florida", "Palm Beach", "Doctor"],
  ["Florida", "Broward", "Doctor"],
  ["Florida", "Palm Beach", "Scientist"]
]

我想按第一项升序、第二项升序和第三项升序排序。结果会是:
[
  ["Florida", "Broward", "Doctor"],
  ["Florida", "Palm Beach", "Doctor"],
  ["Florida", "Palm Beach", "Scientist"],
  ["Pennsylvania", "Bucks", "Doctor"],
  ["New Jersey", "Essex", "Firefighter"],
  ["New Jersey", "Essex", "Lawyer"],
]

我似乎无法通过使用迭代器进行排序来解决这个问题。我试过这个:
collection.sort_by {|a,b| a <=> b }
 => [["Florida", "Palm Beach", "Doctor"], ["Florida", "Palm Beach", "Doctor"], ["New Jersey", "Essex", "Firefighter"], ["New Jersey", "Essex", "Lawyer"], ["Florida", "Broward", "Scientist"], ["Pennsylvania", "Bucks", "Doctor"]]

显然不是我期望的结果。我做错什么了?

最佳答案

这里有两个工具,每一个都可以得到相同的结果,但是在性能方面有不同的结果。sort_by必须对每个项进行一次和一次转换,以便进行比较和排序。sort必须为每个比较运行该块,其中每个排序操作通常执行n x个日志(n)比较。对于可以比数组中的条目数多得多的操作的大型列表。
如果你正在做一个昂贵的转换,sort_by是这里的赢家。对于真正死气沉沉的简单操作来说,sort有时更好,但这是一个主观的要求。
例如,两种方法可以得到相同的结果:

array = [ 7, 2, 5, 3, 4, 1, 6 ]

array.sort_by { |a| -a }
# => [7, 6, 5, 4, 3, 2, 1]

# Sort by negated values
array.sort { |a,b| -a <=> -b }
# => [7, 6, 5, 4, 3, 2, 1]

# Reverse the comparison, reverse the sort order
array.sort { |a,b| b <=> a }

所有这些都是有效的方法,但是当您像这样最小化代码时,sort_by方法的优势就变得更加明显:
# Sort by unary minus (Integer#-@)
array.sort_by(&:-@)

在您的具体案例中,假设您希望以不区分大小写的方式进行排序:
collection = [
  ["NEW JERSEY", "Essex", "Lawyer"],
  ["Florida", "Palm Beach", "Doctor"],
  ["New Jersey", "ESSEX", "Firefighter"],
  ["Pennsylvania", "Bucks", "Doctor"],
  ["florida", "Broward", "Doctor"],
  ["Florida", "Palm Beach", "Scientist"]
]

s = collection.sort_by do |e|
  e.map(&:downcase)
end
# => [["florida", "Broward", "Doctor"], ["Florida", "Palm Beach", "Doctor"], ... ]

在数组上调用downcase是一个比较昂贵的操作,因此您希望尽可能少地调用它,以避免创建大量需要垃圾收集的重复对象。

关于ruby - 按子数组中的三个项目排序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53054135/

10-12 00:22
查看更多