【问题标题】:Multiple field sort_by combination of reverse and not多个字段 sort_by 组合的 reverse 和 not
【发布时间】:2019-08-15 09:14:16
【问题描述】:

所以我从数据库中得到了这个对象数组,我必须按顺序对其进行排序:

  1. 按分数(反向)
  2. 按计数(反向)
  3. 按名称

我已经尝试了所有三个反向但我需要的是最后一个不应该是反向 (DESC) 这是我的代码:


new_data = data.sort_by{ |t| [t.score, t.matches_count, t.name] }.reverse


结果

[
            {
                "id": null,
                "team_id": 939,
                "name": "DAV",
                "matches_count": 2,
                "score": 100.0
            },
            {
                "id": null,
                "team_id": 964,
                "name": "SAN",
                "matches_count": 1,
                "score": 100.0
            },
            {
                "id": null,
                "team_id": 955,
                "name": "PAS",
                "matches_count": 1,
                "score": 100.0
            },
            {
                "id": null,
                "team_id": 954,
                "name": "PAR",
                "matches_count": 1,
                "score": 100.0
            },
            {
                "id": null,
                "team_id": 952,
                "name": "NUE",
                "matches_count": 1,
                "score": 100.0
            }
        ]

预期结果应该按名称按 ASC 顺序而不是 DESC 我知道我的代码是错误的,因为 t.name.reverse 内,但是如果我在前 2 个之后单独按 name 重新排序它,我会得到错误的答案它只会按名称而不是按 3 排序。我也尝试从查询中使用.order("name DESC"),所以当反向它会去 ASC 但没有运气。谢谢!

【问题讨论】:

  • @noname 是的,我已经尝试过,正如您在问题的最后一部分中看到的那样,它将仅按名称返回数据,而不是按(先得分,然后匹配然后名称)。谢谢!
  • 我刚注意到,所以我删除了评论。

标签: ruby-on-rails ruby api ruby-on-rails-5


【解决方案1】:
data = [{:score=>100.0, :matches_count=>2, :name=>"DAV"},
        {:score=>100.0, :matches_count=>1, :name=>"SAN"},
        {:score=>100.0, :matches_count=>1, :name=>"PAS"},
        {:score=>110.0, :matches_count=>1, :name=>"PAR"},
        {:score=>100.0, :matches_count=>1, :name=>"NUE"}] 

data.sort_by{ |h| [-h[:score], -h[:matches_count], h[:name]] }
  #=> [{:score=>110.0, :matches_count=>1, :name=>"PAR"},
  #    {:score=>100.0, :matches_count=>2, :name=>"DAV"},
  #    {:score=>100.0, :matches_count=>1, :name=>"NUE"},
  #    {:score=>100.0, :matches_count=>1, :name=>"PAS"},
  #    {:score=>100.0, :matches_count=>1, :name=>"SAN"}] 

您也可以使用Array#sort,它不需要按降序排序的值是数字,只要它们是可比较的,也就是说,只要它们响应方法:<=>

data.sort do |t1, t2|
  case t1[:score] <=> t2[:score]
  when -1
     1
  when  1
    -1
  else
    case t1[:matches_count] <=> t2[:matches_count]
    when -1
       1
    when  1
      -1
    else
      t1[:name] <=> t2[:name]
    end
  end
end
  #=> <as above>

【讨论】:

  • 我不认为使用 - 而不是 .reverse 我之前尝试过的是 data.sort_by{ |t| [t.score.reverse, t.matches_count.reverse, t.name] } 这就是为什么它返回 undefined method `reverse' 非常感谢!
【解决方案2】:

除了使用-,还可以尝试使用! 反转排序,如下所示:https://www.ruby-forum.com/t/sort-by-multiple-fields-with-reverse-sort/197361/2

所以在你的情况下,你可以这样做:

new_data = data.sort_by{ |t| [!t.score, !t.matches_count, t.name] }

这应该会给您与预期相同的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    相关资源
    最近更新 更多