2011-08-30 86 views
2

這段代碼很難看,如何做得更好?如何通過ruby中的特定對象字段拆分對象的數組?

todos = Todo.all 

@todos_1 = Array.new 
@todos_2 = Array.new 
@todos_3 = Array.new 

todos.each do |doc| 
    if doc.category == nil 
    @ntodos_1 << doc 
    end 
    if doc.category == "something" 
    @todos_2 << doc 
    end 
    if doc.frame == "whatever" 
    @todos_3 << doc 
    end 
+0

如果'doc.frame =='whatever'&& doc.category =='something''會發生什麼?你能否提供一個適當的代碼應該做的規範,最好包括測試用例? –

回答

1

補充現有的答案,讓我們假設您正在使用「正常」 Ruby對象的工作,而不是一個ORM:

todos_by_category = todos.group_by(&:category) 

的情況下使用:

>> todos_by_category["some_category"] 
#=> [todo1, todo2, ...] 
+0

上面提到的範圍解決方案非常方便。我正在探索Ruby,你的答案就是我正在尋找的。謝謝! –

3

您可以使用Todo.group("category").order("category")組織結果集,然後遍歷它,知道當類別改變你在接下來的分組。

或者,它可能是有用的,爲藤堂模型創建範圍:

class Todo < ActiveRecord::Base 
    scope :something, where(:category => "something") 
    scope :whatever, where(:category => "whatever") 
end 

這將允許你指定的結果,實例變量,而不是迭代控制器範圍內的結果:

@something = Todo.something 
@whatever = Todo.whatever 
+0

很好!但是在這種情況下,它會發送兩個數據庫請求。如果我只想發送一個數據庫請求並在Ruby中進行分裂,該怎麼辦? –

+0

答案的第一部分會給你一個解決方案。基本上,你需要保留對之前迭代進行比較的參考。當他們不匹配時,你在下一個類別。 –

0

至少前兩個if的可以在一個情況下,進行組合:

todos.each do |doc| 
    case doc.category 
    when nil 
     @ntodos_1 << doc 
    when "something" 
     @todos_2 << doc 
    end 
    if doc.frame == "whatever" 
    @todos_3 << doc 
    end  

你也知道ELSIF? }

相關問題