按反向值对字符串数组进行排序

时间:2019-03-20 22:46:24

标签: ruby

现在,我产生了以下代码来对域列表进行排序

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

我试图找到一种使这种方式更优雅的方法,因为它看起来似乎不是解决此问题的最佳解决方案,但是我在弄清什么是问题上遇到了问题。

谢谢您的帮助!

2 个答案:

答案 0 :(得分:3)

这对您有用吗?

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

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

答案 1 :(得分:3)

如果您要做的只是按照取反的值排序,请使用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"]