按子数组中的三个项目排序

时间:2018-10-29 21:32:07

标签: ruby algorithm sorting

给出以下集合:

 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"]] 

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

2 个答案:

答案 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"], ... ] 是一个比较昂贵的操作,因此您希望尽可能少地重复一次,以避免创建大量需要垃圾回收的重复对象。