Mam klasę 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 = []
Chcę pchnąć MyClass#item1
do unique_array_of_item1
, ale tylko jeśli unique_array_of_item1
nie zawierają że item1
jeszcze. Znam proste rozwiązanie: po prostu iteruj my_array
i sprawdź, czy unique_array_of_item1
już zawiera bieżący, item1
czy nie.
Czy jest jakieś wydajniejsze rozwiązanie?
Set#each
iSet#to_a
) delegowane@hash
. A od Ruby 1.9 Hashe są zamawiane. „Hashe wyliczają ich wartości w kolejności, w jakiej zostały wstawione odpowiednie klucze”. ruby-doc.org/core-1.9.1/Hash.html@Coorasse ma dobrą odpowiedź , chociaż powinna to być:
my_array | [item]
I zaktualizować
my_array
na miejscu:my_array |= [item]
źródło
my_array |= [item]
który zostanie zaktualizowanymy_array
na miejscu|=
działa dobrze w moich testach z 2.1.1. Opisz swój przypadek testowy lub otwórz nowe pytanie.Nie musisz wykonywać iteracji
my_array
ręcznie.my_array.push(item1) unless my_array.include?(item1)
Edytować:
Jak zauważa Tombart w swoim komentarzu, używanie
Array#include?
nie jest zbyt wydajne. Powiedziałbym, że wpływ na wydajność jest pomijalny w przypadku małych tablic, ale możesz chcieć wybraćSet
większe.źródło
array.include?(item)
ma złożonośćO(n)
- więc przypomina iterację całej tablicy. spójrz na ten test porównawczy: gist.github.com/deric/4953652Możesz przekonwertować item1 na tablicę i dołączyć do nich:
my_array | [item1]
źródło
|
nie||
(patrz odpowiedź Jasona)Należy pamiętać, że klasa Set i | Metoda (zwana także „Set Union”) zwróci szereg unikalnych elementów, co jest świetne, jeśli nie chcesz mieć duplikatów, ale będzie nieprzyjemną niespodzianką, jeśli masz nieunikalne elementy w swojej oryginalnej tablicy zgodnie z projektem.
Jeśli masz co najmniej jeden zduplikowany element w oryginalnej tablicy, którego nie chcesz stracić, iterowanie po tablicy z wczesnym zwrotem jest najgorszym przypadkiem O (n), co nie jest takie złe w ogólnym schemacie .
class Array def add_if_unique element return self if include? element push element end end
źródło
Nie jestem pewien, czy to idealne rozwiązanie, ale zadziałało:
host_group = Array.new if not host_group.kind_of?(Array) host_group.push(host)
źródło