给出以下集合:
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"],
]
我似乎无法通过使用sort_by迭代器来弄清楚。我尝试过:
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"]]
显然不是我期望的结果。我在做什么错了?
答案 0 :(得分:2)
要使用Enumerable#sort_by
时,您正在使用Array#sort
。
Enumerable#sort_by
使用一组键映射枚举,该键是通过给定块映射枚举中的值而生成的。
Array#sort
该块必须实现a和b之间的比较,并且当b跟随a时返回小于0的整数,当a和b相等时返回0,或者当a跟随b时返回大于0的整数。
答案 1 :(得分:1)
这里有两个工具,每个工具都可以得到相同的结果,但是在性能方面会产生不同的结果。 date1 = (1960,01,01)
date2 = (1990,12,31)
for i range(date1,date2):
df.dob = i
必须变换每个项目一次,并且只能变换一次,以便进行比较和排序。 sort_by
必须运行该块以进行每次比较,其中每个排序操作通常会进行 N x log(N)个比较。对于大型列表,其操作数量可能远大于数组中的条目数量。
如果您要进行昂贵的转换,则sort
是赢家。对于真正简单的操作,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"], ... ]
是一个比较昂贵的操作,因此您希望尽可能少地重复一次,以避免创建大量需要垃圾回收的重复对象。