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

Оглавление книги

Оглавление статьи/книги

Генерация: 0.040. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз