Ответ 1
Вы можете использовать Set вместо Array.
У меня есть класс Ruby
class MyClass
attr_writer :item1, :item2
end
my_array = get_array_of_my_class() #my_array is an array of MyClass
unique_array_of_item1 = []
Я хочу нажать MyClass#item1
на unique_array_of_item1
, но только если unique_array_of_item1
еще не содержит этого item1
. Существует простое решение, которое я знаю: просто перейдите через my_array
и проверьте, содержит ли unique_array_of_item1
текущий item1
или нет.
Есть ли более эффективное решение?
Вы можете использовать Set вместо Array.
У @Coorasse есть хороший ответ, хотя так и должно быть:
my_array | [item]
И обновить my_array
на месте:
my_array |= [item]
Вам не нужно вручную перебирать my_array
.
my_array.push(item1) unless my_array.include?(item1)
Edit:
Как указывает Томбарт в своем комментарии, использование Array#include?
не очень эффективно. Я бы сказал, что влияние производительности незначительно для небольших массивов, но вы можете пойти с Set
для более крупных.
Вы можете преобразовать item1 в массив и присоединиться к ним:
my_array | [item1]
Важно помнить, что класс Set и | метод (также называемый "Set Union" ) даст массив уникальных элементов, что отлично, если вы не хотите дубликатов, но который будет неприятным сюрпризом, если у вас есть неповторимые элементы в исходном массиве по дизайну.
Если у вас есть хотя бы один дублирующий элемент в исходном массиве, который вы не хотите потерять, повторение через массив с ранним возвратом - это наихудший вариант O (n), который не так уж плох в великом схема вещей.
class Array
def add_if_unique element
return self if include? element
push element
end
end
Я не уверен, что это идеальное решение, но работал у меня:
host_group = Array.new if not host_group.kind_of?(Array)
host_group.push(host)