У меня есть класс 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#each
иSet#to_a
), делегируются@hash
. А по состоянию на Ruby 1.9 Хеши заказаны. «Хеши перечисляют свои значения в том порядке, в котором были вставлены соответствующие ключи». ruby-doc.org/core-1.9.1/Hash.htmlУ @Coorasse есть хороший ответ , хотя он должен быть:
my_array | [item]
И обновить
my_array
на месте:my_array |= [item]
источник
my_array |= [item]
которыйmy_array
|=
работает в моих тестах с 2.1.1. Опишите свой тестовый пример или откройте новый вопрос.Вам не нужно перебирать
my_array
вручную.my_array.push(item1) unless my_array.include?(item1)
Редактировать:
Как отмечает Томбарт в своем комментарии, использование
Array#include?
не очень эффективно. Я бы сказал, что влияние на производительность незначительно для небольших массивов, но вы можете захотеть пойти сSet
более крупными.источник
array.include?(item)
имеет сложностьO(n)
- это похоже на повторение всего массива. взгляните на этот тест: gist.github.com/deric/4953652[1, 2, 3, 4, 5].bsearch { |e| e == 3 }
Вы можете преобразовать 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)
источник