【问题标题】:Sort a array of string by the reverse value按反向值对字符串数组进行排序
【发布时间】:2019-03-20 22:46:23
【问题描述】:

现在我已经生成了以下代码来对域列表进行排序

domains = [
  'api.test.google.com',
  'dev.blue.google.com',
  'dev.test.google.com',
  'a.blue.google.com'
]

filtered = []

domains.each { |domain| filtered.push domain.reverse! }
domains.sort!
domains.each { |domain| filtered.push domain.reverse! }

这段代码的输出将是:

["a.blue.google.com", "dev.blue.google.com", "api.test.google.com", "dev.test.google.com"]

我正在尝试找到一种方法来使其更加优雅,因为它看起来不是解决此问题的最佳解决方案,但我在弄清楚什么是问题时遇到了问题。

感谢您的帮助!

【问题讨论】:

    标签: ruby


    【解决方案1】:

    这对你有用吗?

    domains.
      map{|d| d.split(".")}.
      sort_by(&:reverse).
      map{|d| d.join(".") }
    

    编辑:或者确实

    domains.sort_by{|x| x.split(".").reverse}
    

    补充一点,我认为像这样的东西应该是一个值对象,因为它们不仅仅是字符串,它们有自己的属性和特殊行为(例如这种类型)。

    例如:

    class Domain
      include Comparable
    
      def initialize(string)
        @string = string
      end
    
      def to_s
        @string
      end
    
      def elements
        @string.split(".")
      end
    
      protected def <=>(other)
        elements.reverse <=> other.elements.reverse
      end
    
      def tld
        elements.last
      end
    end
    

    那么你可以:

    domains = [
      Domain.new('api.test.google.com'),
      Domain.new('dev.blue.google.com'),
      Domain.new('dev.test.google.com'),
      Domain.new('a.blue.google.com'),
    ]
    
    domains.map(&:to_s)
     => ["api.test.google.com", "dev.blue.google.com", "dev.test.google.com", "a.blue.google.com"] 
    
    domains.sort.map(&:to_s)
     => ["a.blue.google.com", "dev.blue.google.com", "api.test.google.com", "dev.test.google.com"] 
    

    您还可以添加您喜欢的任何其他行为,例如返回顶级域的方法。

    【讨论】:

      【解决方案2】:

      如果您只想按相反的值排序,请使用sort_by

      domains = [
        'api.test.google.com',
        'dev.blue.google.com',
        'dev.test.google.com',
        'a.blue.google.com'
      ]
      
      domains.sort_by { |domain| domain.reverse }
      
      #=> ["a.blue.google.com", "dev.blue.google.com", "api.test.google.com", "dev.test.google.com"]
      

      如果您担心将点之间的字符串保持在原始顺序中,您可以使用:

      domains.sort_by { |domain| domain.split('.').reverse }
      
      #=> ["a.blue.google.com", "dev.blue.google.com", "api.test.google.com", "dev.test.google.com"]
      

      【讨论】:

      • ...或domains.sort_by(&amp;:reverse)
      • 在这些域中反转用于排序的字符串只是一个巧合。尝试排序['az.com', 'by.com', 'cx.com']。它也没有考虑层次结构。
      猜你喜欢
      • 1970-01-01
      • 2014-10-28
      • 1970-01-01
      • 2021-06-27
      相关资源
      最近更新 更多