Ajouter un élément à un tableau s’il n’y est pas déjà

J’ai une classe 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 = [] 

Je veux pousser MyClass#item1 vers unique_array_of_item1 , mais seulement si unique_array_of_item1 ne contient pas encore cet item1 . Il existe une solution simple que je connais: il suffit de parcourir le my_array et de vérifier si unique_array_of_item1 contient déjà l’ item1 ou non.

Y a-t-il une solution plus efficace?

Vous pouvez utiliser Set au lieu de Array.

Coorasse a une bonne réponse, même si elle devrait être:

 my_array | [item] 

Vous n’avez pas besoin de parcourir my_array .

 my_array.push(item1) unless my_array.include?(item1) 

Modifier:

Comme Tombart le souligne dans son commentaire, utiliser Array#include? n’est pas très efficace. Je dirais que l’impact sur la performance est négligeable pour les petites baies, mais vous pourriez vouloir utiliser Set pour les plus grandes.

Vous pouvez convertir item1 en tableau et les joindre:

 my_array | [item1] 

Important de garder à l’esprit que la classe Set et le | La méthode (également appelée “Set Union”) donnera un tableau d’éléments uniques , ce qui est génial si vous ne voulez pas de doublons mais ce sera une mauvaise surprise si vous avez des éléments non uniques dans votre tableau d’origine.

Si vous avez au moins un élément dupliqué dans votre tableau d’origine que vous ne voulez pas perdre, l’itération dans le tableau avec un retour anticipé est le pire des cas, O (n), ce qui n’est pas trop grave dans le grand schéma. .

 class Array def add_if_unique element return self if include? element push element end end 

Je ne sais pas si c’est la solution parfaite, mais j’ai travaillé pour moi:

  host_group = Array.new if not host_group.kind_of?(Array) host_group.push(host)