У меня есть массив @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>
Таким образом, вопрос состоит в том, как я могу проверить, включали ли моему массиву уже "лошадь" так, чтобы я не заполнял его той же лошадью?
Массивы в Ruby не имеют метода exists?
, но у них есть метод include?
, как описано в документы .
Что-то вроде
unless @suggested_horses.include?(horse)
@suggested_horses << horse
end
должно работать из коробки.
Почему бы не сделать это, просто выбрав восемь разных чисел от 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)
.
#include?
должен работать, он работает для общих объектов , а не только для строк. Ваша проблема в примере кода заключается в следующем тесте:
unless @suggested_horses.exists?(horse.id)
@suggested_horses<< horse
end
(даже при условии использования #include?
). Вы пытаетесь искать конкретный объект, а не идентификатор. Так должно получиться так:
unless @suggested_horses.include?(horse)
@suggested_horses << horse
end
ActiveRecord переопределил оператор сравнения для объектов, чтобы они смотрели только на его состояние (новый / созданный) и идентификатор
Это ...
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
Метод массива 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