【问题标题】:Sorting: Sort array based on multiple conditions in Ruby排序:在 Ruby 中根据多个条件对数组进行排序
【发布时间】:2012-02-11 20:49:21
【问题描述】:

我有一个像这样的多维数组:

[
  [name, age, date, gender]
  [name, age, date, gender]
  [..]
]

我想知道根据多个条件对该数组进行排序的最佳方法...例如,我将如何根据 age first 然后按名称进行排序?

我像这样搞乱sort 方法:

array.sort { |a,b| [ a[1], a[0] ] <=> [ b[1], b[0] ] }

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

【问题讨论】:

标签: ruby arrays sorting


【解决方案1】:

这应该可以解决问题:

array.sort { |a,b| [ a[1], a[0] ] <=> [ b[1], b[0] ] }

那么这有什么作用呢?它使用了很多 Ruby 习语。

  • 首先是块,它有点像其他语言中的回调或匿名函数/类。 Array 的sort 方法使用它们根据块的返回值比较两个元素。您可以阅读所有关于它们的信息here
  • 接下来是&lt;=&gt; 运算符。如果第一个参数小于第二个,则返回 -1,如果相等则返回 0,如果第一个参数大于第二个,则返回 1。当您将它与数组一起使用时,它将逐元素比较数组,直到其中一个返回 -1 或 1。如果数组相等,您将得到 0。

【讨论】:

  • 你也可以使用sort_by { |a| [a[1], a[0]] },构建所有这些数组并不是免费的。
【解决方案2】:

据我了解,您想先按年龄排序,然后如果多个记录具有相同的年龄,请按名称排列该子集。


这对我有用

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

这样做是先按年龄比较,如果年龄相同( 返回 0),则比较名称。

【讨论】:

  • 非常好!我喜欢这种语法
  • 如果年龄相同,然后我们要按降序对名称进行排序?
  • @Inquisitive 那么在这种情况下,我认为您会在右侧的“(a [1] b [1])”中切换“a”和“b”。
【解决方案3】:

您应该始终使用sort_by 进行键控排序。它不仅可读性更强,而且效率也很多。此外,为了可读性,我还更喜欢使用解构绑定:

array.sort_by {|name, age| [age, name] }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 2018-11-01
    • 2013-11-10
    • 2020-10-27
    • 2023-02-01
    • 2019-02-12
    • 2012-11-02
    相关资源
    最近更新 更多