2013-12-16 52 views
0

我有行爲像通過空間多維數組,像一個數組:如何解析多維數組中的值,並根據條件選擇另一個?

「角色」=> [ 「1主編0」, 「1個主編1」, 「2編輯器0」, 「2編輯器1」 ,「14編輯0」,「15編輯0」],「提交」=>「授予訪問」,「ID」=>「3」}

每個數組值代表[category_id,user.title,checked_boolean]和來自

form 
<%= hidden_field_tag "roles[]", [c.id, "editor", 0] %> 
<%= check_box_tag "roles[]", [c.id, "editor", 1 ], !!checked %> 

我處理它使用拆分

params[:roles].each do |role| 
    cat_id = role[0].split(" ")[0] 
    title = role.split(" ")[1] 
    checked_boolean = role.split(" ")[2] 
end 

給出頂部的數組,您可以看到「Category 1」&「Category 2」被選中,而「Cat 14」和「Cat 15」沒有被選中。

我想比較給定數組的值,並且如果對於給定的category_id都存在,我想擺脫「checked_boolean = 0」的值。這樣,如果布爾值爲1,我可以檢查角色是否已經存在,如果沒有,則創建它。如果它是0,我可以檢查角色是否存在,如果存在,請刪除它。

我怎麼能做到這一點?我想像params [:roles] .uniq那樣做,但不知道如何僅在第一次拆分時處理uniq。

或者有沒有更好的方式發佈Rails中的「unchecks」?我發現了處理簡單複選框的取消選中操作的解決方案,可以輸入true/false,但是我的情況不同,因爲除了User之外,還需要傳遞true/false。標題:

+0

到parsedata使用下表:'(CAT_ID,標題,checked_boolean)= role.split「「' –

+0

我怎麼能檢查是否有重複的cat_ids ,並刪除「checked_boolean == false」的那個? – kibaekr

回答

2

我們的params[:roles]是:

[ 「1主編0」, 「1主編1」, 「2編輯器0」, 「2編輯器1」, 「14編輯0」, 「15編輯0」]

的轉換和過濾示例如下:

roles = params[:roles].map {| role | role.split " " } 
filtered = roles.select do| role | 
    next true if role[ 2 ].to_i == 1 
    count = roles.reduce(0) {| count, r | r[ 0 ] == role[ 0 ] && count + 1 || count} 
    count == 1 
end 

# => [["1", "editor", "1"], ["2", "editor", "1"], ["14", "editor", "0"], ["15", "editor", "0"]] 

filtered.map {| role | role.join(' ') } 

由於select方法返回一個新的過濾角色數組,因此可以在上面看到結果數組。但是,當然你仍然可以使用和源params[:roles],和中間(在map方法工作後)角色數組版本。

最後,你可以舉出結果數組到文本形式:

filtered.map {| role | role.join(' ') } 
=> ["1 editor 1", "2 editor 1", "14 editor 0", "15 editor 0"] 
+0

謝謝你的幫助!那麼我將如何能夠調用處理的數組?我會在該循環中創建另一個數組嗎? – kibaekr

+0

'select'和'map'總是會創建另一個數組。 –

+0

我不知道我明白。所以如果我想用底部列出的處理過的數組,我能夠使用「角色」嗎?當我在代碼後面「放置角色」時,它仍然顯示重複項 – kibaekr

1

majioa的解決方案肯定是更簡潔,更好地利用語言的功能,但這裏是我對其採取了更加語言無關做法。我剛剛開始學習Ruby,因此我將此作爲學習的機會,但它確實解決了您的問題。

my_array = ["1 editor 0", "1 editor 0", "1 editor 1", "2 editor 0", 
      "2 editor 1", "14 editor 0", "15 editor 0"] 

puts "My array before:" 
puts my_array.inspect 

# As we're nesting a loop inside another for each loop 
# we can't delete from the same array without confusing the 
# iterator of the outside loop. Instead we'll delete at the end. 
role_to_del = Array.new 

my_array.each do |role| 
    cat_id, checked_boolean = role.split(" ")[0], role.split(" ")[2] 
    if checked_boolean == "1" 
    # Search through the array and mark the roles for deletion if 
    # the category id's match and the found role's checked status 
    # doesn't equal 1. 
    my_array.each do |s_role| 
     s_cat_id = s_role.split(" ")[0] 
     if s_cat_id != cat_id 
     next 
     else 
     s_checked_boolean = s_role.split(" ")[2] 
     role_to_del.push s_role if s_checked_boolean != "1" 
     end 
    end 
    end 
end 

# Delete all redundant roles 
role_to_del.each { |role| my_array.delete role } 

puts "My array after:" 
puts my_array.inspect 

輸出:

My array before: 
["1 editor 0", "1 editor 0", "1 editor 1", "2 editor 0", "2 editor 1", "14 editor 0", 
"15 editor 0"] 
My array after: 
["1 editor 1", "2 editor 1", "14 editor 0", "15 editor 0"] 
+0

謝謝你的解決方案!我喜歡雙循環的想法!我實際上正在計劃使用類似於此的操作,但不確定創建2個數組是否有效。但是,似乎majioa的解決方案也創建了2個數組,所以我想最後它是一樣的? – kibaekr

+0

不用擔心,我可以幫忙。這隻會創建一個數組並重用params數組,如果你用params [:roles]交換my_array的每個實例並忽略第一行,我就這樣寫下來,這樣你就可以將它轉儲到一個ruby文件中並且非常容易地測試它。使用可用的庫函數是傳統的看法,因爲它通常會減少代碼(如majioa的解決方案所示),並且可以在後臺包含性能優化。我以爲我會發布我的解決方案,以便了解發生的事情證明是不可逾越的 – RodgerB

相關問題