Подтвердить что ты не робот

Сортировка: сортировка массива на основе нескольких условий в Ruby

У меня есть mulitdimensional массив, например:

[
  [name, age, date, gender]
  [name, age, date, gender]
  [..]
]

Мне интересно, как лучше отсортировать этот массив на основе нескольких условий... Например, как бы я сортировать на основе age сначала, а затем по имени?

Я возился с методом sort следующим образом:

array.sort { |a,b| [ a[1], a[0] ] <=> [ b[1], b[0] ] }

Кроме того, я не совсем понимаю этот синтаксис, я не получаю ожидаемых результатов. Должен ли я использовать метод sort? Должен ли я отдельно сравнивать результаты mapping с массивом?

4b9b3361

Ответ 1

Вы всегда должны использовать sort_by для ключевого типа. Это не только намного более читаемо, но и намного эффективнее. Кроме того, я бы предпочел также использовать деструктурирующее связывание для удобочитаемости:

ary.sort_by {|name, age| [age, name] }

Ответ 2

Это должно сделать трюк:

array.sort { |a,b| [ a[1], a[0] ] <=> [ b[1], b[0] ] }

Итак, что это делает? Он использует много идиом Ruby.

  • Сначала это блоки, которые похожи на обратные вызовы или анонимные функции/классы на других языках. Метод sort Array использует их для сравнения двух элементов на основе возвращаемого значения блока. Вы можете прочитать все о них здесь.
  • Следующий оператор <=>. Он возвращает -1, если первый аргумент меньше второго, 0, если они равны, и 1, если первый больше второго. Когда вы используете его с массивами, он будет сравнивать массивы по-разному, пока один из них не вернет -1 или 1. Если массивы равны, вы получите 0.

Ответ 3

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


Это работает для меня

people = [
      ["bob", 15, "male"], 
      ["alice", 25, "female"], 
      ["bob", 56, "male"], 
      ["dave", 45, "male"], 
      ["alice", 56, "female"], 
      ["adam", 15, "male"]
    ]

people.sort{|a,b| (a[1] <=> b[1]) == 0 ? (a[0] <=> b[0]) : (a[1] <=> b[1]) }

# The sorted array is

[["adam", 15, "male"], 
 ["bob", 15, "male"], 
 ["alice", 25, "female"], 
 ["dave", 45, "male"], 
 ["alice", 56, "female"], 
 ["bob", 56, "male"]]

Что это такое, сначала сравнивается по возрасту, и если возраст тот же (< = > returs 0), он сравнивает имя.