, используя sort_by в рубине (для рельсов)?

19

Итак, я создал собственный массив таких пользователей:

[["user1",432],["user1",53],["user9",58],["user5",75],["user3",62]]

Я хочу отсортировать их по значению 2n'd в каждом массиве, от самого большого до самого маленького. У меня есть чувство, использующее sort или sort_by для массивов, это способ сделать это, но я не уверен, как это сделать.

    
задан Elliot 05.02.2012 в 10:21
источник

3 ответа

40

sort_by

Если вы заинтересованы в sort_by , вы можете разрушить свои внутренние массивы

array.sort_by { |_, x| x }.reverse

или вызовите оператор индекса

array.sort_by { |x| x[1] }.reverse

Вместо реверсирования вы можете отменить значения, возвращаемые из блока.

array.sort_by { |_, x| -x }
array.sort_by { |x| -x[1] }

Еще одна альтернатива - использовать ampersand и Array#last .

array.sort_by(&:last).reverse

сортировать

Решение с использованием sort может быть

array.sort { |x, y| y[1] <=> x[1] }
    
ответ дан Jan 05.02.2012 в 10:27
источник
  • +1 для разных решений :) –  Vasiliy Ermolovich 05.02.2012 в 10:32
  • Если вы хотите получить полноту, вы можете включить array.sort_by (&: last) .reverse. –  mu is too short 05.02.2012 в 10:42
  • , но для полноты вам нужно добавить простой массив .sort_by {| u, uid | -uid}. Кроме того, обратите внимание, что это могло бы выиграть от использования Enumerable # reverse_each для более эффективного использования пространства (когда перечислитель подходит, конечно). –  tokland 05.02.2012 в 11:34
  • Я сталкиваюсь с проблемами при использовании sort или sort_by в моем ведущем и контроллере. В нем указан неопределенный метод sort_by. Может ли кто-нибудь пролить свет на это? –  Alex Jose 19.05.2015 в 10:59
  • извините, этот вопрос не связан, можете ли вы объяснить, как работает ваше первое и второе решение, спасибо –  YasirAzgar 11.11.2016 в 10:48
2

используйте это: array.sort_by { |a| -a[1] }

    
ответ дан Vasiliy Ermolovich 05.02.2012 в 10:25
источник
  • Я всегда был головоломкой sort_by, не имея обратной опции. –  tokland 05.02.2012 в 11:28
  • nit-picking: распаковывание аргументов блока считается более идиоматичным, поскольку доступ к ним как к массиву. –  tokland 05.02.2012 в 11:35
0

Еще одно решение для sort_by в обратном порядке ( - не работает во всех случаях, подумайте о сортировке по строке):

class Invertible
  include Comparable
  attr_reader :x

  def initialize(x)
    @x = x
  end

  def <=> (x)
    x.x <=> @x
  end
end

class Object
  def invertible
    Invertible.new(self)
  end
end

[1, 2, 3].sort_by(&:invertible) #=> [3, 2, 1]
["a", "b", "c"].sort_by(&:invertible) #=> ["c", "b", "a"]

В простом случае он медленнее, чем обратный, но может работать лучше со сложными типами:

objs.sort_by do |obj|  
  [obj.name, obj.date.invertible, obj.score, ...]
end
    
ответ дан Victor Moroz 05.02.2012 в 18:35
источник