83 votes

Comment vérifier si mon tableau inclut un objet?

J'ai un tableau @horses = [] que je remplis avec du hasard chevaux.

Comment puis-je vérifier si mon @horses gamme inclut un cheval qui est déjà inclus (existe) dans tout ça?

J'ai essayé quelque chose comme:

@suggested_horses = []
  @suggested_horses << Horse.find(:first,:offset=>rand(Horse.count))
  while @suggested_horses.length < 8
    horse = Horse.find(:first,:offset=>rand(Horse.count))
    unless @suggested_horses.exists?(horse.id)
       @suggested_horses<< horse
    end
  end

J'ai aussi essayé avec include? mais j'ai vu c'était pour cordes seulement. Avec exists? j'obtiens l'erreur suivante:

undefined method `exists?' for #<Array:0xc11c0b8>

La question est donc comment puis-je vérifier si mon tableau a déjà un "cheval" inclus, de sorte que je n'ai pas le remplir avec le même cheval?

184voto

Tomasz Points 784

Les tableaux en Ruby n'ont pas de méthode exists? . Et ils ont la méthode include? décrite dans la documentation . Quelque chose comme

 unless @suggested_horses.include?(horse)
   @suggested_horses << horse
end
 

devrait fonctionner en boîte.

3voto

MBO Points 12516

#include? doit travailler, il travaille pour des objets généraux, non seulement les chaînes de caractères. Votre problème dans l'exemple de code est de ce test:

unless @suggested_horses.exists?(horse.id)
  @suggested_horses<< horse
end

(même en supposant à l'aide de #include?). Vous essayez de rechercher un objet, pas une pièce d'identité. Donc, il devrait être comme ceci:

unless @suggested_horses.include?(horse)
  @suggested_horses << horse
end

ActiveRecord a redéfini comparaison de l'opérateur pour les objets afin de prendre un coup d'oeil seulement pour son état (nouveau/créé) et id

3voto

Pourquoi ne pas le faire simplement en choisissant huit nombres différents parmi 0 Horse.count et utiliser cela pour obtenir vos chevaux?

 offsets = (0...Horse.count).to_a.sample(8)
@suggested_horses = offsets.map{|i| Horse.first(:offset => i) }
 

Cela a l'avantage supplémentaire de ne pas créer de boucle infinie si vous avez moins de 8 chevaux dans votre base de données.

Remarque: Array#sample est nouveau pour 1.9 (et pour venir en 1.8.8), donc améliorez votre Ruby, require 'backports' ou utilisez quelque chose comme shuffle.first(n) .

1voto

John Topley Points 58789

La méthode include? Array accepte n'importe quel objet, pas seulement une chaîne. Cela devrait fonctionner:

 @suggested_horses = [] 
@suggested_horses << Horse.first(:offset => rand(Horse.count)) 
while @suggested_horses.length < 8 
  horse = Horse.first(:offset => rand(Horse.count)) 
  @suggested_horses << horse unless @suggested_horses.include?(horse)
end
 

0voto

Chris McCauley Points 9764

Cette ...

 horse = Horse.find(:first,:offset=>rand(Horse.count))
unless @suggested_horses.exists?(horse.id)
   @suggested_horses<< horse
end
 

Devrait probablement être ceci ...

 horse = Horse.find(:first,:offset=>rand(Horse.count))
unless @suggested_horses.include?(horse)
   @suggested_horses<< horse
end
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X