【问题标题】:sort_by and tap on hashsort_by 并点击哈希
【发布时间】:2018-03-09 17:08:39
【问题描述】:

所以我对 Ruby 和一般编码还很陌生,最近发现了 tap 以及它如何解决我的一些三明治代码。所以我尝试使用tap 来清理下面的方法。当我看到我的代码时,我意识到第一个示例看起来更干净,但在弄清楚为什么第二个示例确实返回原始对象数组时仍然会得到一些帮助。

def sort_arr
  my_var = my_arr.sort_by { |obj| obj.price['usd'] }
  my_var.reverse
end

这有效并根据价格方法的值返回我的对象​​的排序数组。我以为我可以用 tap 做到这一点,但它返回了原始数组

def sort_arr
  my_arr.sort_by { |obj| obj.price['usd'] }.tap do |my_obj|
    my_obj.reverse
  end
end

【问题讨论】:

    标签: ruby sorting object methods


    【解决方案1】:

    tap 将始终返回调用它的对象(即x.tap { ... } 始终为x)。

    您的方法可以简化为:

    def sort_arr
      my_arr.sort_by { |obj| obj.price['usd'] }.reverse
    end
    

    或者,如果价格是数字,

    def sort_arr
      my_arr.sort_by { |obj| -obj.price['usd'] }
    end
    

    【讨论】:

    • 感谢@Amadan 的解释和建议!
    • 另外,x.tap(&:reverse!)(注意爆炸)可以在这里工作(尽管tap 仍然是绝对多余的,)感谢变异Array#reverse!。 /cc @scarsam
    【解决方案2】:

    tap 将始终返回它被调用的对象

    此方法的主要目的是“利用”方法链,以便对链中的中间结果执行操作。

    你可以只使用sort来优化你的代码

    #For reverse order compare obj2 price with obj1 price
    def sort_arr
      my_arr.sort { |obj1, obj2| obj2.price['usd'] <=> obj1.price['usd'] }
    end
    
    #For increasing order compare obj1 price with obj2 price
    def sort_arr
      my_arr.sort { |obj1, obj2| obj1.price['usd'] <=> obj2.price['usd'] }
    end
    

    【讨论】:

    • "你可以只使用sort来优化你的代码" - sort,一般来说,比sort_by使用更少的空间,但是更多的时间 (因为它调用块O(n log n) 次,而sort_by 调用块O(n) 次)。例如,我的系统使用 sort_by 对 100 个元素的数组进行排序的速度是原来的两倍。大多数人不会考虑使用sort“优化”,除非您的内存不足。
    • 关于 tap 的“主要目的”,我怀疑它在调试中的用途就在那里,因为可以简单地在两个链式方法之间插入 .tap { |e| puts "e=#{e} }
    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 2012-02-13
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 2016-10-25
    相关资源
    最近更新 更多