Книга: Программирование на языке Ruby
8.1.4. Сравнение массивов
8.1.4. Сравнение массивов
При сравнении массивов возможны неожиданности — будьте осторожны!
Для сравнения массивов служит метод экземпляра <=>
. Он работает так же, как в других контекстах, то есть возвращает -1 (меньше), 0 (равно) или 1 (больше). Методы ==
и !=
опираются на реализацию метода <=>
.
Массивы сравниваются поэлементно; первая же пара несовпадающих элементов определяет результат всего сравнения. (Предпочтение отдается левее расположенным элементам, как при сравнении двух длинных целых чисел «на глазок», когда мы сравниваем по одной цифре за раз.)
а = [1, 2, 3, 9, 9]
b = [1, 2, 4, 1, 1]
с = а <=> b # -1 (то есть а < b)
Если все элементы равны, то массивы считаются равными. Если один массив длиннее другого и все элементы вплоть до длины более короткого массива равны, то более длинный массив считается большим.
d = [1, 2, 3]
е = [1, 2, 3, 4]
f = [1, 2, 3]
if d < е # false
puts "d меньше e"
end
if d == f
puts "d равно f" # Печатается "d равно f"
end
Поскольку класс Array
не подмешивает модуль Comparable
, то обычные операторы сравнения <
, >
, <=
и >=
для массивов не определены. Но при желании их легко определить самостоятельно:
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.1. Создание и инициализация массива
- 8.1.2. Доступ к элементам массива и присваивание им значений
- 8.1.3. Определение размера массива
- 8.1.4. Сравнение массивов
- 8.1.5. Сортировка массива
- 8.1.6. Выборка из массива по заданному критерию
- 8.1.7. Специализированные функции индексирования
- 8.1.8. Реализация разреженной матрицы
- 8.1.9. Массивы как математические множества
- 8.1.10. Рандомизация массива
- 8.1.11. Многомерные массивы
- 8.1.12. Нахождение элементов, принадлежащих одному массиву и не принадлежащих другому
- 8.1.13. Преобразование или отображение массивов
- 8.1.14. Удаление из массива элементов равных nil
- 8.1.15. Удаление заданных элементов из массива
- 8.1.16. Конкатенирование массивов и добавление в конец массива
- 8.1.17. Использование массива в качестве стека или очереди
- 8.1.18. Обход массива
- 8.1.19. Преобразование массива в строку с разделителями
- 8.1.20. Обращение массива
- 8.1.21. Удаление дубликатов из массива
- 8.1.22. Чередование массивов
- 8.1.23. Вычисление частоты различных значений в массиве
- 8.1.24. Инвертирование массива для получения хэша
- 8.1.25. Синхронная сортировка нескольких массивов
- 8.1.26. Указание значения по умолчанию для новых элементов массива
- 8.1.22. Чередование массивов
- Сравнение клиентов именованных каналов и сокетов
- Сравнение
- Временное сравнение
- 14.4. Сравнение языков программирования
- 8.1.13. Преобразование или отображение массивов
- 8.1.16. Конкатенирование массивов и добавление в конец массива
- 4.2 Сравнение SAN и NAS
- Сравнение C# и C++
- Материнская плата имеет возможность организации RAID-массивов из двух SATA-дисков. Можно ли подключить к ней только один...
- Типы массивов в Delphi
- 3.2. Сравнение операционных систем