迭代序列并一次更改一个对象的最佳方法(Ruby)
我是ruby新手,觉得我仍然用C语言的夏普风格做很多事情:-)。 假设您有一个对象数组(问题:has_many=>:答案)。 我想迭代所有答案,如果一些答案符合条件,则更改答案属性。 目前,我的工作如下:迭代序列并一次更改一个对象的最佳方法(Ruby),ruby,Ruby,我是ruby新手,觉得我仍然用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 还有什么其他方法可以做到
def iterate_and_do_stuff
for (a in self.answers)
if(a.somecriteria==true)
a.some_attr=some_val
end
end
end
还有什么其他方法可以做到这一点?块、环等
请再见
谢谢。使用:
self.answers.each{a | a.some_attr=some_val if a.some_criteria}
只是为了好玩一个选择
self.answers.select{|a| a.some_criteria}.each{|a| a.some_attr = some_val}
或
不过,这两种方法的效率都不如您的原始代码。我更喜欢map!或收集!在这种情况下,因为您可以使用!方法在语义上表示正在就地更改数组
self.answers.map!{ |a|
a.some_criteria ? (a.some_attr = some_val) : a.some_attr
}
或
通过这种方式,很明显您打算更改阵列。如果您使用的是ActiveRecord模型,请不要忘记,您可以在数据库级别而不是内存中进行选择。换言之,您可以从数据库中只检索到要放入数组的值,然后只需更改这些值 下面是一个使用自定义查找器的示例(有点像以前的方法):
类问题{:已接受=>true}
结束
结束
结束
类答案
或者你也可以与其他协会合作:
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! }
类问题“Answer”,:conditions=>{:接受的=>true}
结束
类答案
下面是另一个在子类上使用命名作用域(更新一点,在我看来是首选)的示例:
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! }
类问题{:已接受=>true}
结束
q=问题。查找:首先
q、 答案。接受。每个{a{a}做点什么!}
但在任何情况下,您都抽象了“选择”,它有一些好处:
把这个转换成…结束挡块怎么样?比我快2分钟。他妈的必须查找文档。所以看起来总是像一场竞赛:-)它也将比使用#select后跟#each更有效,因为您只需在数组上迭代一次。
self.answers.collect!{ |a|
a.some_criteria ? (a.some_attr = some_val) : a.some_attr
}
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! }