Как я проверяю, чтобы видеть, включает ли мой массив объект?

У меня есть массив @horses = [] то, что я заполняюсь некоторыми случайными лошадями.

Как я могу проверить если мой @horses массив включает лошадь, которая уже включена (существует) в нем?

Я попробовал что-то как:

@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

Я также попробовал include? но я видел, что это было для строк только. С exists? Я получаю следующую ошибку:

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

Таким образом, вопрос состоит в том, как я могу проверить, включали ли моему массиву уже "лошадь" так, чтобы я не заполнял его той же лошадью?

73
задан the Tin Man 29 June 2013 в 04:29
поделиться

5 ответов

Массивы в Ruby не имеют метода exists? , но у них есть метод include? , как описано в документы . Что-то вроде

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

должно работать из коробки.

172
ответ дан 24 November 2019 в 12:10
поделиться

Почему бы не сделать это, просто выбрав восемь разных чисел от 0 до Horse.count и не использовать их, чтобы получить своих лошадей?

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

Это имеет дополнительное преимущество, заключающееся в том, что он не вызовет бесконечного цикла, если в вашей базе данных меньше 8 лошадей.

Примечание: Array # sample является новым для 1.9 (и появится в 1.8.8), поэтому либо обновите свой Ruby, потребуйте 'backports' , либо используйте что-то вроде shuffle.first (n) .

3
ответ дан 24 November 2019 в 12:10
поделиться

#include? должен работать, он работает для общих объектов , а не только для строк. Ваша проблема в примере кода заключается в следующем тесте:

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

(даже при условии использования #include? ). Вы пытаетесь искать конкретный объект, а не идентификатор. Так должно получиться так:

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

ActiveRecord переопределил оператор сравнения для объектов, чтобы они смотрели только на его состояние (новый / созданный) и идентификатор

2
ответ дан 24 November 2019 в 12:10
поделиться

Это ...

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

Вероятно, должно быть это ...

horse = Horse.find(:first,:offset=>rand(Horse.count))
unless @suggested_horses.include?(horse)
   @suggested_horses<< horse
end
0
ответ дан 24 November 2019 в 12:10
поделиться

Метод массива include? принимает любой объект, а не только строку. Это должно сработать:

@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
1
ответ дан 24 November 2019 в 12:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: