Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Массив нельзя назвать идеальным средством для представления множества, поскольку он может содержать дубликаты. Если вы хотите трактовать массив как множество, то дубликаты можно удалить (с помощью метода
uniq
uniq!
Над множествами производятся две основные операции: объединение и пересечение. Для этого применяются операторы
|
&
а = [1, 2, 3, 4, 5]
b = [3, 4, 5, 6, 7]
с = a | b # [1, 2, 3, 4, 5, 6, 7]
d = а & b # [3,4,5]
# Дубликаты удаляются...
e = [1, 2, 2, 3, 4]
f = [2, 2, 3, 4, 5]
g = e & f # [2; 3, 4]
Для объединения множеств можно использовать и оператор конкатенации (
+
Метод
-
а = [1, 2, 3, 4, 5]
b = [4, 5, 6, 7]
с = а - b # [1, 2, 3]
# Отметим, что наличие элементов 6 and 7 не отражается на результате.
Для «аккумулирования» множеств можно применять оператор
|=
а |= b
а = а | b
&=
Для массивов не определена операция ИСКЛЮЧАЮЩЕЕ ИЛИ, но мы можем без труда реализовать ее. В терминах теории множеств она соответствует выборке тех элементов, которые входят в объединение двух множеств, но не входят в их пересечение.
class Array
def ^(other)
(self | other) - (self & other)
end
end
x = [1, 2, 3, 4, 5]
y = [3, 4, 5, 6, 7]
z = x ^ y # [1, 2, 6, 7]
Чтобы проверить, входит ли некий элемент в множество, пользуйтесь методом
include?
member?
Comparable
x = [1, 2, 3]
if x.include? 2
puts "yes" # Печатается "yes"
else
puts "no"
end
Конечно, это некоторое отступление от канонов математики, где для обозначения принадлежности множеству применяется символ, похожий на греческую букву эпсилон. Отступление в том смысле, что множество находится слева, а не справа от оператора, то есть мы спрашиваем не «принадлежит ли данный элемент множеству», а «содержит ли множество данный элемент».
Многим это безразлично. Но привыкшие к языку Pascal или Python (или впитавшие математический формализм с молоком матери) хотели бы, чтобы было по-другому. Такую возможность мы реализуем в следующем фрагменте:
class Object
def in(other)
other.include? self
end
end
x = [1, 2, 3]
if 2.in x
puts "yes" # Печатается "yes"
else
puts "no"
end
Лично я отправил запрос на изменение Ruby (RCR 241) с предложением ввести в язык оператор
in
У этой идеи есть свои достоинства (к тому же
in
Теперь обратимся к подмножествам и надмножествам. Как определить, является ли данное множество подмножеством или надмножеством другого? Встроенных методов для этого нет, но мы можем поступить следующим образом:
class Array
def subset?(other)
self.each do |x|
if !(other.include? x)
return false
end
end
true
end
def superset?(other)
other.subset?(self)
end
end
a = [1, 2, 3, 4]
b = [2, 3]
с = [2, 3, 4, 5]
flag1 = c.subset? a # false
flag2 = b.subset? a # true
flag3 = c.superset? b # true
Обратите внимание: мы выбрали «естественный» порядок, то есть задаем вопрос
x.subset?у
x
у?
Для распознавания пустого множества достаточно проверить, пуст ли массив. Это делает метод
empty?
Операция дополнения опирается на идею универсального множества. Однако «универсальное множество» в каждой конкретной ситуации определяется по-разному, поэтому лучшим решением будет самое простое: сначала определим, что такое универсальное множество, а потом вычислим разность.