Сортировать массив строк по обратному значению - PullRequest
0 голосов
/ 21 марта 2019

Прямо сейчас я создал следующий код для сортировки списка доменов

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 ]

3 голосов
/ 21 марта 2019

Если все, что вы хотите сделать, это отсортировать по обратному значению, используйте 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"]
3 голосов
/ 21 марта 2019

Будет ли это работать для вас?

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

Вы также можете добавить любое другое поведение, например, способ возврата домена верхнего уровня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...