массиве. (Как всегда, эта величина на единицу больше индекса последнего элемента.)
x = ['а', 'b', 'с', 'd']
а = x.length # 4
b = x.size # 4
Метод nitems
отличается от предыдущих тем, что не учитывает элементы равные nil
:
у = [1, 2, nil, nil, 3, 4]
с = у.size # 6
d = у.length # 6
е = y.nitems # 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