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

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

Жанры

Программирование на языке 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"]

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

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Первый среди равных. Книга V

Бор Жорж
5. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга V

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

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Я до сих пор князь. Книга XXII

Дрейк Сириус
22. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я до сих пор князь. Книга XXII

Ефрейтор. Назад в СССР. Книга 2

Гаусс Максим
2. Второй шанс
Фантастика:
попаданцы
альтернативная история
7.00
рейтинг книги
Ефрейтор. Назад в СССР. Книга 2

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

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

На границе империй. Том 10. Часть 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 4

Император Пограничья 3

Астахов Евгений Евгеньевич
3. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 3

Советник 2

Шмаков Алексей Семенович
7. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Советник 2

Идеальный мир для Лекаря 20

Сапфир Олег
20. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 20

Эволюционер из трущоб

Панарин Антон
1. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб

Матабар V

Клеванский Кирилл Сергеевич
5. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар V

Слэпшот

Хоуп Ава
Невозможно устоять. Горячие романы Авы Хоуп
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Слэпшот

Как я строил магическую империю 7

Зубов Константин
7. Как я строил магическую империю
Фантастика:
попаданцы
постапокалипсис
аниме
фантастика: прочее
5.00
рейтинг книги
Как я строил магическую империю 7