Ruby替代.each()使用一个项目

时间:2014-09-19 09:19:29

标签: ruby-on-rails ruby

我厌倦了使用if循环,因为.each函数在应用于一个对象时不起作用。

例如:

@groups = ...
users = User.find(params[:selected_users])

if params[:selected_users].count == 1  # case with one object
  users.some_method()
else                          # case with multiple objects
  users.each do |user|
    user.some_method()
  end
end

是否有一个与.each相同的函数,只是在应用于一个对象时返回该对象?

5 个答案:

答案 0 :(得分:1)

你可以写:

Array(users).each do |user|
  user.some_method
end

Array()的一些例子。如果使用单个参数调用:

> Array(:foo)
# => [:foo]

如果使用已经是数组的东西调用:

> Array([:foo])
# => [:foo]

答案 1 :(得分:1)

你可以这样:

users = Array.wrap(User.find(params[:selected_users]))
#users is now always an array
users.each do |user|
  # do stuff
end

Array.wrap处理一些优于Array()

的边缘情况

例如:

x = {a: "b", c: "d"}

Array(x)
# => [[:a, "b"], [:c, "d"]]

Array.wrap(x)
# =>[{:a=>"b", :c=>"d"}]

答案 2 :(得分:0)

您可以使用find_each

User.where(id: params[:selected_users]).find_each do |user|
  user.some_method
end

如果你想跟他们做一些事情,这是行不通的。我刚刚注意到您的@groups,如果您之后需要在视图中使用它们,那么您将需要其他建议之一。

答案 3 :(得分:0)

您可以使用arr对数组each执行的操作:

arr.each{|e| ...} #=> arr

您可以使用obj

对单个对象tap执行操作
obj.tap{|e| ...} #=> obj

答案 4 :(得分:0)

我同意所有答案都打算解决与ActiveRecord相关的问题。

但是,另一种选择可能是将每个对象扩展到每个对象,因此只在对象本身上进行迭代。

例:

class Object
  def each
   if block_given?
     [self].each { |e| yield(e) }
   end
end

我不是核心Ruby的出口,所以我不知道副作用会是什么,但它似乎有效....

1.each{|i|puts i}
=> [1]
[1,2,3].each{|i|puts i}
=> [1, 2, 3]