(Ruby) как вернуть -1 специально для конкретного сравнения - PullRequest
0 голосов
/ 08 октября 2009

скажем, когда я сравниваю значения в ruby, я имею в виду, что независимо от того, что я хочу, использование сортировки по этому значению и все остальное возвращает -1 (поэтому это значение по умолчанию сортируется как меньшее, чем все ).

например, скажем, я хочу, чтобы '100' сортировал меньше в 100% случаев против 99. Так что, если я сортирую значения в массиве, и сравнение получается между 100 и 99, 100 сортируется меньше (т.е. возвращается -1). но я хочу, чтобы все остальные случаи были нормальными (98 меньше 99, 50 больше 30 и т. д.)

редактировать: хорошо, это то, что я хочу

если у меня есть x и y, я не хочу использовать

x <=> y

я хочу использовать (в псевдокоде и волнистости)

x > y

, что означает, что х всегда больше, чем у

Ответы [ 6 ]

1 голос
/ 08 октября 2009

Легче обрабатывать особенность вне сортировки!

module Enumerable
  def sort_excluding(*vals)
    special,rest = partition {|x| vals.include?(x)}
    rest.sort + special
  end
end
1 голос
/ 08 октября 2009

Почему бы вам вместо этого не использовать словарь для хранения значений, связанных с их относительным значением? В этом случае строку abc можно сопоставить с -1, а затем просто убедиться, что никакие другие значения не отображаются на значения, равные или меньшие -1. ​​

Редактировать: Если вас интересует только одно конкретное значение, нарушающее норму, то это решение не для вас.

0 голосов
/ 09 октября 2009

Я думаю, что вы хотите:

[30, 50, 4, 0, 100, -22, 99].sort_by {|a| [a == 100 ? -1 : 0, a ]}.reverse

, что дает:

99
50
30
 4
 0
-22
100

Надеюсь, я понял вопрос!

0 голосов
/ 09 октября 2009

Array#sort или Enumerable#sort (я не знаю, что вы пытаетесь отсортировать) может занять препятствующий блок. Если указан блок, блок используется для сравнения вместо <=>

Например, этот код будет сортировать в обратном порядке:

foo.sort { |a,b| b <=> a }

В вашем случае вам нужно позвонить #sort примерно так:

foo.sort do |a,b|
  if [a,b].sort == [99,100]
    b-a # returns 1 or -1 so that 99 > 100
  else
    a <=> b
  end
end

Я не совсем уверен в том, как вы пытаетесь сортировать, но это должно позволить вам использовать сортировку так, как вам нужно. Больше информации о Array#sort и любом другом методе можно найти в вашем linux (и, возможно, других ОС) через ri, например: ri Array#sort.

0 голосов
/ 08 октября 2009

Один из способов сделать это - реализовать производный класс для пользовательских сопоставлений (http://www.ruby -doc.org / core / classes / Comparable.html )

Вот пример кода (и тесты) для вас:

class StrA < String
 include Comparable
 attr :str
 def <=>(anOther)
  if (str == "abc" && anOther.str == "abc")
   0
  elsif (str == "abc")
   -1
  elsif (anOther.str == "abc")
   1
  else
   str <=> anOther.str
  end
 end

 def initialize(str)
  @str = str
 end

 def inspect
  @str
 end
end

И тесты:

a = StrA.new("Z")
b = StrA.new("B")
c = StrA.new("abc")
d = StrA.new("")

a > b # 1
a > c # 1
c > a # -1
d > c # 1
c > d # -1
c < d # 1
c > d # -1

[a, b, c, d].sort! # [ "Z", "B", "", "abc"]
0 голосов
/ 08 октября 2009

Вы можете переопределить метод сортировки для объекта следующим образом:

class Fixnum
  alias old_sort <=>

  def <=>(object)
    if (self == 100 or object == 100)
      return -1
    else
      return self.old_sort object
    end
  end
end

puts (101 <=> 100)

Редактировать 1: Выше приведен полностью рабочий пример.

Редактировать 2: Как сказал Йоханнес в комментариях, вам не следует реализовывать этот точный код. Это всего лишь простой пример того, как переопределить ваш метод сортировки для выполнения логики, специфичной для предметной области. Кроме того, обновлен код, чтобы отразить другой комментарий Йоханнеса о сравнении как с объектом, так и с самим собой.

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