迭代序列并一次更改一个对象的最佳方法(Ruby)

时间:2009-03-05 14:45:55

标签: 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

有什么其他方法可以做到这一点?块,循环等?

请adivce。

谢谢。

5 个答案:

答案 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! }

但在任何一种情况下,你都抽象了“选择”,这有一些好处:

  1. 大型藏品时更快
  2. 您已将较低级别的选择标准抽象为具有更高级别语义含义的内容,这使您的代码更易于阅读和维护