[英]Is there more idiomatic ruby to perform this iteration?
我正在遍歷一組id並希望返回第一個對象,當對其調用謂詞方法時,該對象返回true
。 幾行代碼值得千言萬語:
def applicable_question(question_ids)
ordered_ids(question_ids, order).detect do |question_id|
question = Question.find_by(id: question_id)
return question if question.applicable_for?(self)
end
end
剝離域名條款:
def desired_thing(ids)
ids.detect do |id|
thing = Thing.new(id)
return thing if thing.true?
end
end
這里有更慣用的方法嗎? 具體來說,我覺得我在濫用detect
。 我立刻伸手去拿each
並且break
,但是這種方法並沒有走得太遠。
對此代碼的要求是它不需要實例化大量對象(例如ActiveRecord子類型)來查找所需的對象。
你有:
desired_thing = ids.detect do |id|
thing = Thing.new(id)
return thing if thing.true?
end
如果找到哪個thing
。 thing.true?
是true
, detect
不會返回的元素ids
(被分配到desired_thing
因為它是由搶占) return
。 另一方面,如果塊完成而沒有return
被調用,則detect
返回nil
並將該值desired_thing
,但是在desired_thing
的代碼中該nil
值沒有用。 因此,最好只寫:
ids.each do |id|
thing = Thing.new(id)
return thing if thing.true?
end
我想你差不多了。
從find_by_id
方法,我假設Question
是一個具有某種ActiveRecord
功能的類,所以我希望where
方法也存在。
在這種情況下:
applicable_question = Question.where(id: ids).order(...).detect do |question|
question.applicable_for?(self)
end
會做得很好。
它不像濫用detect
,你只需要擁有正確的可枚舉對象集。
如果實例化太多對象不是一個可接受的解決方案,那么https://stackoverflow.com/a/29176622/687142是可行的方法。 請記住,這兩種方法都有其缺點。
Question.where(id: ids).order(...).detect {|q| q.condition? }
Question.where(id: ids).order(...).detect {|q| q.condition? }
會做一個查詢到數據庫,但實例化對象太多。 ids.each {|id| q = Question.find(id); return q if q.condition? }
ids.each {|id| q = Question.find(id); return q if q.condition? }
將執行過多的數據庫查詢,但一次只能實例化一個對象 第一種方法是持續繁重(記憶明智),而第二種方法的性能取決於您檢索記錄的順序,並且也可能變得非常昂貴。
最佳選擇也取決於您的數據集。 如果你有成千上萬的問題,那么第一種方法是不可能的。
也許最好的選擇是嘗試以某種方式訂購記錄condition?
更可能是真的
你所擁有的與你想要做的事情相去甚遠。 我會做的事情如下:
desired_thing = ids.detect{ |id| Thing.new(id) }
我不確定你是否試圖遠離像find_by_id這樣的SQL方法,或者在哪里,但我相信你也可以使用它們,除非你需要使用detect(或find)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.