我是红宝石的新手,觉得我仍然以C的方式做很多事情:-)。 假设您有一个对象数组(问题:has_many =>:答案)。 我想迭代所有答案,如果某些答案符合条件,请更改答案属性。 目前我正在做如下:
def iterate_and_do_stuff
for (a in self.answers)
if(a.somecriteria==true)
a.some_attr=some_val
end
end
end
有什么其他方法可以做到这一点?块,循环等?
请adivce。
谢谢。
答案 0 :(得分:12)
使用Array#each:
self.answers.each {|a| a.some_attr = some_val if a.some_criteria}
答案 1 :(得分:4)
我更喜欢地图!还是收集!在这种情况下,因为你可以使用!语义上表示你正在改变数组的方法。
self.answers.map!{ |a|
a.some_criteria ? (a.some_attr = some_val) : a.some_attr
}
或
self.answers.collect!{ |a|
a.some_criteria ? (a.some_attr = some_val) : a.some_attr
}
这样很清楚你打算改变数组。
答案 2 :(得分:2)
self.answers.select{|a| a.somecriteria}.each{|a| a.some_attr = some_val}
OR
self.answers.find_all{|a| a.somecriteria}.each{|a| a.some_attr = some_val}
但两者的效率都低于原始代码。
答案 3 :(得分:1)
只是为了好玩另类
self.answers.select{|a| a.some_criteria}.each{|a| a.some_attr = some_val}
答案 4 :(得分:1)
如果您正在使用ActiveRecord模型,请不要忘记您可以在数据库级别而不是在内存中进行选择。换句话说,您只能从数据库中检索您想要进入数组的值,然后只需更改它们。
这是一个使用自定义查找程序的示例(一种较旧的方法):
class Question < ActiveRecord::Base
has_many :answers do
def accepted
find :all, :conditions => { :accepted => true }
end
end
end
class Answer < ActiveRecord::Base
belongs_to :question
end
q = Question.find :first
q.answers.accepted.each { |a| a.do_something! }
或者你可以用另一个协会来做:
class Question < ActiveRecord::Base
has_many :answers
has_many :accepted_answers, :class_name => "Answer", :conditions => { :accepted => true }
end
class Answer < ActiveRecord::Base
belongs_to :question
end
q = Question.find :first
q.accepted_answers.each { |a| a.do_something! }
这是另一个使用命名范围(在我看来更新一点,在我看来更喜欢)的例子:
class Question < ActiveRecord::Base
has_many :answers
end
class Answer < ActiveRecord::Base
belongs_to :question
named_scope :accepted, :conditions => { :accepted => true }
end
q = Question.find :first
q.answers.accepted.each { |a| a.do_something! }
但在任何一种情况下,你都抽象了“选择”,这有一些好处: