web-dev-qa-db-fra.com

Ajoute un élément à un tableau s'il n'y est pas déjà

J'ai un cours de rubis

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 à unique_array_of_item1, mais seulement si unique_array_of_item1 ne contient pas encore ce item1. Il existe une solution simple que je connais: il suffit de parcourir my_array et de vérifier si unique_array_of_item1 contient déjà le item1 actuel ou non.

Y a-t-il une solution plus efficace?

78
Alan Coromano

Vous pouvez utiliser Set au lieu de Array.

76
Jiří Pospíšil

@Coorasse a bonne réponse , mais il devrait l'être:

my_array | [item]

Et pour mettre à jour my_array en place:

my_array |= [item]
88
Jason Denney

Vous n'avez pas besoin de parcourir my_array à la main.

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

Modifier:

Comme le souligne Tombart dans son commentaire, utiliser Array#include? n’est pas très efficace. Je dirais que l'impact sur les performances est négligeable pour les petits tableaux, mais vous pouvez vouloir utiliser Set pour les plus grands. 

35
doesterr

Vous pouvez convertir item1 en tableau et les rejoindre:

my_array | [item1]
29
coorasse

Il est important de garder à l'esprit que la classe Set et le | method (é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 qui sera une mauvaise surprise si vous avez des éléments non uniques dans votre tableau d'origine.

Si vous ne voulez pas perdre au moins un élément dupliqué dans votre tableau d'origine, itérer dans le tableau avec un retour anticipé est le pire des cas, O (n), ce qui n'est pas si mal dans le grand schéma des choses .

class Array
  def add_if_unique element
    return self if include? element
    Push element
  end
end
2
elreimundo

Je ne sais pas si c'est la solution parfaite, mais a fonctionné pour moi:

    Host_group = Array.new if not Host_group.kind_of?(Array)
    Host_group.Push(Host)
0
witkacy26