Методы сортировки массивов в Ruby

С самого начала сортировка была предметом озабоченности компьютерных ученых. Было много алгоритмы это вошло и вышло из употребления, и все еще сегодня новые алгоритмы расширяют границы производительности. Будучи языком высокого уровня, вы не будете реализовывать алгоритмы сортировки в Рубин если вы заботитесь о производительности, и, кроме того, сортировка Массивы и другие коллекции - это еще больше вещей, которые Ruby делает для вас.

Технически, сортировка - это работа, выполняемая модулем Enumerable. Модуль Enumerable - это то, что связывает все типы коллекций в Ruby. Он обрабатывает коллекции, сортирует, просматривает и находит определенные элементы и т. Д. Как Enumerable сортирует коллекцию, остается загадкой, или, по крайней мере, так и должно быть. Фактический алгоритм сортировки не имеет значения, единственное, что вам нужно знать, это то, что объекты в коллекции сравниваются с помощью «оператора космического корабля».

«Оператор космического корабля» берет два объекта, сравнивает их и затем возвращает -1, 0 или 1. Это немного расплывчато, но сам оператор не имеет четко определенного поведения. Давайте возьмем числовые объекты для примера. Если у вас есть два числовых объекта

instagram viewer
и би оценить <=> бна что будет рассчитывать выражение? В случае с Numerics это легко сказать. Если a больше, чем b, это будет -1, если они равны, это будет 0, а если b больше, чем a, это будет 1. Это используется для указания алгоритму сортировки, какой из двух объектов должен идти первым в массив. Просто помните, что если левый операнд должен стоять первым в массиве, он должен иметь значение -1, если правая рука должна быть первой, это должно быть 1, а если это не имеет значения, это должно быть 0.

Это не всегда следует таким аккуратным правилам. Что произойдет, если вы используете этот оператор для двух объектов разных типов? Вы, вероятно, получите исключение. Что происходит, когда вы звоните 1 <=> 'Обезьяна'? Это будет эквивалент вызова 1. <=> ( 'Обезьяна')Это означает, что фактический метод вызывается на осталось операнд и Fixnum # <=> возвращает ноль, если правый операнд не является числовым. Если оператор возвращает nil, метод sort вызовет исключение. Итак, перед сортировкой массивов убедитесь, что они содержат объекты, которые можно сортировать.

Во-вторых, фактическое поведение оператора космического корабля не определено. Он определен только для некоторых базовых классов, а для ваших пользовательских классов полностью зависит от того, что вы хотите, чтобы они имели в виду. Если у тебя есть Ученик В классе вы можете сортировать учеников по фамилии, имени, уровню обучения или их комбинации. Поэтому всегда помните, что поведение оператора космического корабля и сортировка не определены должным образом ни для чего, кроме базовых типов.

У вас есть массив числовых объектов, и вы хотите отсортировать их. Есть два основных способа сделать это: Сортировать и Сортировать!. Первый создает копию массива, сортирует его и возвращает. Вторая сортирует массив на месте.

Это довольно очевидно. Итак, давайте возьмем это на ступеньку выше. Что если вы не хотите полагаться на оператора космического корабля? Что делать, если вы хотите совершенно другое поведение? Эти два метода сортировки принимают необязательный параметр блока. Этот блок принимает два параметра и должен давать значения так же, как оператор космического корабля: -1, 0 и 1. Итак, учитывая массив, мы хотим отсортировать его так, чтобы все значения, которые делятся на 3, шли первыми, а все остальные - после. Фактический порядок здесь не имеет значения, только те, которые делятся на 3, на первом месте.

Как это работает? Сначала обратите внимание на аргумент блока в методе sort. Во-вторых, обратите внимание на деление по модулю на параметры блока и повторное использование оператора космического корабля. Если один кратен 3, по модулю будет 0, в противном случае это будет 1 или 2. Поскольку 0 будет сортировать до 1 или 2, здесь имеет значение только модуль. Использование параметра блока особенно полезно в массивах, которые имеют более одного типа элемента, или когда вы хотите отсортировать пользовательские классы, у которых нет определенного оператора космического корабля.

Есть еще один метод сортировки, называемый Сортировать по. Однако, прежде чем заняться sort_by, вы должны понять, как переводить массивы и коллекции с помощью map.