排序:根据Ruby中的多个条件对数组进行排序

pru*_*ett 21 ruby arrays sorting

我有一个多维数组,如下所示:

[
  [name, age, date, gender]
  [name, age, date, gender]
  [..]
]
Run Code Online (Sandbox Code Playgroud)

我想知道根据多种条件对这个数组进行排序的最佳方法......例如,我将如何根据年龄 首先按名称进行排序?

我正在搞乱sort这样的方法:

array.sort { |a,b| [ a[1], a[0] ] <=> [ b[1], b[0] ] }
Run Code Online (Sandbox Code Playgroud)

除此之外,我并不真正理解这种语法,我没有得到我期望的结果.我应该使用这种sort方法吗?我应该单独比较mapping阵列的结果吗?

Jör*_*tag 44

您应该始终使用sort_by键控排序.它不仅是更具可读性,也有很多更有效率.此外,为了便于阅读,我还希望再次使用destructuring bind:

ary.sort_by {|name, age| [age, name] }
Run Code Online (Sandbox Code Playgroud)


rob*_*rit 14

这应该做的伎俩:

array.sort { |a,b| [ a[1], a[0] ] <=> [ b[1], b[0] ] }
Run Code Online (Sandbox Code Playgroud)

那这是做什么的呢?它使用了很多Ruby习语.

  • 首先是块,有点像回调或其他语言的匿名函数/类.sortArray 的方法使用它们来根据块的返回值比较两个元素.你可以在这里阅读所有相关信息.
  • 接下来是<=>运营商.如果第一个参数小于第二个参数,则返回-1;如果它们相等则返回0;如果第一个参数大于第二个参数,则返回1.当你将它与数组一起使用时,它会逐个元素地比较数组,直到其中一个返回-1或1.如果数组相等,你将得到0.

  • 你也可以使用`sort_by {| a | [a [1],a [0]]}`,构建所有这些数组并不是免费的. (9认同)

小智 7

根据我的理解,您希望先按年龄排序,然后如果多个记录的年龄相同,请按名称排列该子集.


这适合我

people = [
      ["bob", 15, "male"], 
      ["alice", 25, "female"], 
      ["bob", 56, "male"], 
      ["dave", 45, "male"], 
      ["alice", 56, "female"], 
      ["adam", 15, "male"]
    ]

people.sort{|a,b| (a[1] <=> b[1]) == 0 ? (a[0] <=> b[0]) : (a[1] <=> b[1]) }

# The sorted array is

[["adam", 15, "male"], 
 ["bob", 15, "male"], 
 ["alice", 25, "female"], 
 ["dave", 45, "male"], 
 ["alice", 56, "female"], 
 ["bob", 56, "male"]]
Run Code Online (Sandbox Code Playgroud)

这样做是先按年龄进行比较,如果年龄相同(<=>重新调整0),则比较名称.