Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

 def <(other)

(self <=> other) == -1

 end

 def <=(other)

(self < other) or (self == other)

 end

 def >(other)

(self <=> other) == 1

 end

 def >=(other)

(self > other) or (self == other)

 end

end

Впрочем,

было бы проще включить модуль
Comparable
:

class Array

 include Comparable

end

Определив эти операторы, можно пользоваться ими как обычно:

if а < b

 print "а < b" # Печатается "а < b"

else

 print "а >= b"

end

if d < e

 puts "d < e" # Печатается "d < e"

end

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

<=>
не определен или не имеет смысла. Следующий код приводит к возбуждению исключения (
TypeError
) во время выполнения, так как сравнение
3 <=> "x"
лишено смысла:

g = [1, 2, 3]

h = [1, 2, "x"]

if g < h # Ошибка!

 puts "g < h" # Ничего не выводится.

end

Если и это вас не смущает, то добавим, что сравнение на равенство и неравенство этом случае работает. Объясняется это тем, что объекты разных типов считаются неравными, хотя мы и не можем сказать, какой из них больше.

if g != h # Здесь ошибка не возникает.

 puts "g != h" # Печатается "g != h"

end

Наконец, не исключено, что два массива, содержащих несравнимые типы данных, все равно можно сравнить с помощью операторов

<
и
>
. В примере ниже мы получаем определенный результат еще до того, как натолкнемся на несравнимые элементы:

i = [1, 2, 3]

j = [1, 2, 3, "x"]

if i < j # Здесь ошибка не возникает.

 puts "i < j" # Печатается "i < j"

end

8.1.5. Сортировка массива

Самый простой способ отсортировать массив — воспользоваться встроенным методом

sort
:

words = %w(the quick brown fox)

list = words.sort # ["brown", "fox", "quick", "the"]

#
Или отсортировать на месте:

words.sort! # ["brown", "fox", "quick", "the"]

Здесь предполагается, что все элементы массива сравнимы между собой. При сортировке неоднородного массива, например

[1, 2, "tHRee", 4]
, обычно возникает ошибка.

В подобных случаях можно воспользоваться также блочной формой того же метода. Ниже предполагается, что у каждого элемента есть хотя бы метод

to_s
(преобразующий его в строку):

а = [1, 2, "three", "four", 5, 6]

b = a.sort {|x,y| x.to_s <=> y.to_s}

# b равно [1, 2, 5, 6, "four", "three"]

Конечно, подобное упорядочение (в данном случае основанное на кодировке ASCII) может оказаться бессмысленным. При работе с неоднородным массивом нужно прежде всего задать себе вопрос, зачем вообще его сортировать. И почему приходится хранить в массиве объекты разных типов?

Описанная методика работает, потому что блок возвращает целое число (-1.0 или 1) при каждом вызове. Если возвращена -1, то есть x меньше у, то два элемента меняются местами. Чтобы отсортировать массив по убыванию, достаточно все го лишь изменить порядок сравнения:

x = [1, 4, 3, 5, 2]

y = x.sort {|a,b| b <=> а} # [5, 4, 3, 2, 1]

Блоки можно применять и для более сложных сортировок. Предположим, что нужно отсортировать названия книг и фильмов следующим способом: регистр игнорируется, полностью игнорируются пробелы, а также ряд знаков препинания и артикли. Ниже приведен простой пример (и преподаватели английского языка, и программисты будут удивлены таким способом упорядочения по алфавиту).

titles = ["Starship Troopers",

"A Star is Born",

"Star Wars",

"Star 69",

"The Starr Report"]

sorted = titles.sort do |x,y|

 # Удалить артикли

 a = x.sub(/"(a |an |the )/i, "")

 b = y.sub(/"(a |an |the )/i, "")

 # Удалить пробелы и знаки препинания

 a.delete!(" .,-?!")

 b.delete!(" .,-?!")

 # Преобразовать в верхний регистр

 a.upcase!

 b.upcase!

 # Сравнить а и b

 а <=> b

end

# Теперь sorted равно:

# [ "Star 69", "A Star is Born", "The Starr Report"

# "Starship Troopers", "Star Wars"]

Поделиться:
Популярные книги

Скандальные разводы

Нестерова Дарья Владимировна
Научно-образовательная:
история
5.00
рейтинг книги
Скандальные разводы

История любовная

Шмелев Иван Сергеевич
Проза:
классическая проза
6.25
рейтинг книги
История любовная

Американская звезда

Коллинз Джеки
Любовные романы:
современные любовные романы
8.54
рейтинг книги
Американская звезда

Ткущая. Обманутые секунды

Тарасова Анна
3. Ткущая
Любовные романы:
любовно-фантастические романы
8.27
рейтинг книги
Ткущая. Обманутые секунды

Газлайтер. Том 15

Володин Григорий Григорьевич
15. История Телепата
Фантастика:
боевая фантастика
попаданцы
5.75
рейтинг книги
Газлайтер. Том 15

Всеобщая история

Новиков Сергей Викторович
Научно-образовательная:
история
5.00
рейтинг книги
Всеобщая история

Откройте Америку!

Яцкарь Григорий Семенович
Проза:
современная проза
роман
6.25
рейтинг книги
Откройте Америку!

Верховный суд СССР

Коллектив авторов
Научно-образовательная:
история
юриспруденция
5.00
рейтинг книги
Верховный суд СССР

Выйти из боя. Гексалогия

Валин Юрий Павлович
Выйти из боя
Фантастика:
альтернативная история
8.00
рейтинг книги
Выйти из боя. Гексалогия

Т. 01 Кукловоды

Хайнлайн Роберт Энсон
1. Отцы-основатели. Весь Хайнлайн
Фантастика:
научная фантастика
8.50
рейтинг книги
Т. 01 Кукловоды

Камень. Книга 4

Минин Станислав
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Камень. Книга 4

Тот, кто знает. Книга вторая. Перекресток

Маринина Александра
5.00
рейтинг книги
Тот, кто знает. Книга вторая. Перекресток

Наемные убийцы

Шёвалль Май
5.00
рейтинг книги
Наемные убийцы

Иного не желаю. Часть третья

Лошкарёва Виктория Витальевна
5. Оборотная сторона мира
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Иного не желаю. Часть третья