Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
class Array
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!