【问题标题】:What is the best way to do custom sort?进行自定义排序的最佳方法是什么?
【发布时间】:2021-06-09 05:26:50
【问题描述】:
arr = ["h12020", "h22018", "h22020", "h22019", "h12019"]

expected_arr = ["h22018","h12019","h22019","h12020", "h22020"]

我尝试的方式:

arr.sort { |a, b| a.slice(2, 4) <=> b.slice(2, 4) } # ["h22018","h22019","h12019","h12020", "h22020"]

arr 排序得到expected_arr 的方法是什么?

【问题讨论】:

    标签: arrays ruby-on-rails ruby sorting


    【解决方案1】:

    使用#sort_by 通常更简洁,如下所示:

    arr.sort_by {|a| a.slice(2, 4) + a.slice(1, 1)} 
    # ["h22018", "h12019", "h22019", "h12020", "h22020"]
    

    此外,您可以操作块内的字符串以按您想要的顺序放置它。在这里,我刚刚将您要排序的数字切分并添加到最后。您也可以像 nuaky 一样使用范围。

    #sort 与块一起使用更加灵活,尤其是对于降序等情况。但它不太简洁,并且在您可以使用 #sort_by 的情况下通常表现不佳。

    【讨论】:

    • 性能取决于用例。文档说sort_by“当键集很简单时相当昂贵。”
    • @Stefan 我同意你的第一句话。关于第二句,文档将#sort 方法与未给出块进行比较。基于我在比较两者时所做的有限基准测试,#sort_by(通常,倾向于在此处插入最喜欢的黄鼠狼词)比使用#sort 和宇宙飞船操作员做同样的事情要好。 Matz 在他的书中说:“如果与 sort 关联的块必须进行大量计算才能执行其比较,那么使用 sort_by 会更有效。”因此,正如您所说,性能取决于用例。
    【解决方案2】:

    您可以拆分每个值[a[2..5], a[1..1]] => ["2020", "1"],然后按年份和第一个数字排序:

    arr.sort_by { |a| [a[2..5], a[1..1]] }
    

    这将按年份 (2020, 2019) 排序,然后按其他参数 (1, 2),因此您将得到:

    ["h22018", "h12019", "h22019", "h12020", "h22020"]
    

    【讨论】:

      【解决方案3】:

      与其他答案的语法差异很小,更简洁:

      arr.sort_by { |a| a[2..5] + a[1] } # Ruby
      arr.sort_by { |a| a.last(4) + a[1] } # Rails
      

      【讨论】:

      • 确实没有理由使用slice。最近花太多时间在 JavaScript 上。 :) Ruby 的范围是 JavaScript 可以认真使用的东西。
      【解决方案4】:

      可读性较差,效率较低,但更酷:

      arr.sort_by { _1.chars.rotate(2) }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-07
        • 2015-12-11
        • 2010-12-16
        • 2010-09-06
        相关资源
        最近更新 更多