Сортировка массивов в обратном порядке в Rby
Я новичок в Ruby и мне нужен кусок кода, который мне объяснят. Массив для сортировки:
books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia",
"A Brief History of Time", "A Wrinkle in Time"]
Блок кода ниже сортирует этот массив books
Аризона
books.sort! { |firstBook, secondBook| firstBook <=> secondBook }
Блок кода ниже сортирует этот массив books
ZA
books.sort! { |firstBook, secondBook| secondBook <=> firstBook }
Почему это? Почему первый сортирует AZ, а второй ZA? Я вроде понимаю оператор комбинированного сравнения <=>
, Возвращает -1, 1 или 0 в зависимости от сравнения. Но как это сортировать вещи? Спасибо!
2 ответа
Оператор сортировки делает то, на что он похож: он сообщает вам, что-то меньше, больше или равно другому объекту в порядке сортировки. Итак, ваш первый блок спрашивает firstBook
до или после secondBook
", а второй блок спрашивает" это secondBook
до или после first book
"Как видите, ответ на них противоположный:
- "А" предшествует "Б" (
"A" <=> "B" == -1
) - "Б" идет после "А" (
"B" <=> "A" == 1
)
Таким образом, если вы измените порядок вопроса, вы получите противоположный ответ, а это означает, что алгоритм сортировки (тип сравнения) даст противоположный результат.
Алгоритм сортировки использует возвращаемое значение из блока, в данном случае это результат оператора сравнения (<=>
). когда -1
это вернуть порядок a
а также b
останется прежним (т.е. a
приходит раньше b
В зависимости от значения алгоритм будет сохранять текущий порядок a
а также b
в том, чтобы знать, a
должны быть отсортированы до b
(-1
) или после (1
), или если два эквивалентны (0
).
Алгоритм многократно сравнивает соседние пары элементов, пока все элементы не упорядочены.
Давайте добавим некоторые выходные данные, чтобы увидеть, что происходит, когда вы вызываете sort в вашем списке книг. Это даст нам некоторое представление о том, что делает метод сортировки. Я добавил комментарии, чтобы проиллюстрировать, как каждый шаг сортировки изменял массив книг. Обратите внимание, что говорить о том, как сортировка "меняет" позиции, упрощается в этом примере.
> books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]
> books.sort! do |a, b|
> result = a <=> b
> puts %(\n"#{ a }" <=> "#{ b }" #=> #{ result }) # Print out which elements are being compared and the result
> result
> end
"Charlie and the Chocolate Factory" <=> "War and Peace" #=> -1
# ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"] *** No change
"War and Peace" <=> "Utopia" #=> 1
# ["Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Brief History of Time", "A Wrinkle in Time"] *** Positions of "Utopia" and "War and Peace" are swapped
"Charlie and the Chocolate Factory" <=> "Utopia" #=> -1
# ["Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Brief History of Time", "A Wrinkle in Time"] *** No change
"War and Peace" <=> "A Brief History of Time" #=> 1
# ["Charlie and the Chocolate Factory", "Utopia", "A Brief History of Time", "War and Peace", "A Wrinkle in Time"] *** Positions of "War and Peace" and "A Brief History of Time" are swapped
"Utopia" <=> "A Brief History of Time" #=> 1
# ["Charlie and the Chocolate Factory", "A Brief History of Time", "Utopia", "War and Peace", "A Wrinkle in Time"] *** Positions of "Utopia" and "A Brief History of Time" are swapped
"Charlie and the Chocolate Factory" <=> "A Brief History of Time" #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace", "A Wrinkle in Time"] *** Positions of "Charlie and the Chocolate Factory" and "A Brief History of Time" are swapped
"War and Peace" <=> "A Wrinkle in Time" #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "Utopia", "A Wrinkle in Time", "War and Peace"] *** Positions of "War and Peace" and "A Wrinkle in Time" are swapped
"Utopia" <=> "A Wrinkle in Time" #=> 1
# ["A Brief History of Time", "Charlie and the Chocolate Factory", "A Wrinkle in Time", "Utopia", "War and Peace"] *** Positions of "Utopia" and "A Wrinkle in Time" are swapped
"Charlie and the Chocolate Factory" <=> "A Wrinkle in Time" #=> 1
# ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"] *** Positions of "Charlie and the Chocolate Factory" and "A Wrinkle in Time" are swapped
"A Brief History of Time" <=> "A Wrinkle in Time" #=> -1
# ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"] *** No change
# Done! All elements have been sorted, so the algorithm exits.
=> ["A Brief History of Time", "A Wrinkle in Time", "Charlie and the Chocolate Factory", "Utopia", "War and Peace"]
Когда сравнение меняется с a <=> b
в b <=> a
результаты инвертируются, что приводит к сортировке в обратном порядке.
> books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]
> books.sort! do |a, b|
> result = b <=> a
> puts %(\n"#{ b }" <=> "#{ a }" #=> #{ result }) # Print out which elements are being compared and the result
> result
> end
"A Wrinkle in Time" <=> "A Brief History of Time" #=> 1
"Charlie and the Chocolate Factory" <=> "A Brief History of Time" #=> 1
"Charlie and the Chocolate Factory" <=> "A Wrinkle in Time" #=> 1
"Utopia" <=> "A Brief History of Time" #=> 1
"Utopia" <=> "A Wrinkle in Time" #=> 1
"Utopia" <=> "Charlie and the Chocolate Factory" #=> 1
"War and Peace" <=> "A Brief History of Time" #=> 1
"War and Peace" <=> "A Wrinkle in Time" #=> 1
"War and Peace" <=> "Charlie and the Chocolate Factory" #=> 1
"War and Peace" <=> "Utopia" #=> 1
=> ["War and Peace", "Utopia", "Charlie and the Chocolate Factory", "A Wrinkle in Time", "A Brief History of Time"]
Смотрите также документацию по Array#sort!