我正在開發一個 RoR Web 應用程式。
我必須根據散列值以自定義順序遍歷散列陣列。
在此示例中,“待處理”狀態需要首先出現在串列中。
是否可以在每個回圈中自定義陣列的順序?
<% example_statuses = [{ :status => "Active", :job_count => 0 }, { :status => "Pending", :job_count => 1 }, { :status => "Complete", :job_count => 3 }] %>
<% example_statuses.each do |es| %>
<h3><%= es[:status] %></h3>
<% end %>
更新:我有一個簡單的作業示例,其中涉及洗掉掛起狀態哈希并將其添加回陣列中。但是有沒有辦法創建自定義訂單而不是手動替換值?
<% example_statuses = [{ :status => "Active", :job_count => 0 }, { :status => "Pending", :job_count => 1 }, { :status => "Complete", :job_count => 3 }] %>
<%= pending = example_statuses.find { |x| x[:status] == "Pending"} %>
<% example_statuses.delete(pending) %>
<% example_statuses.prepend(pending) %>
<% example_statuses.each do |es| %>
<h3><%= es[:status] %></h3>
<% end %>
uj5u.com熱心網友回復:
這里有兩個重要的概念:
- 用于
Array#index查找在陣列中找到元素的位置。 - “宇宙飛船操作員”
<=>就是這樣Array#sort作業的。你可以在這里調查
在您的情況下,解決方案是:
example_statuses = [{ :status => "Active", :job_count => 0 }, { :status => "Pending", :job_count => 1 }, { :status => "Complete", :job_count => 3 }]
order = ["Pending", "Active", "Complete"]
sorted_array = example_statuses.sort do |a,b|
order.index(a[:status]) <=> order.index(b[:status])
end
# => [{:status=>"Pending", :job_count=>1}, {:status=>"Active", :job_count=>0}, {:status=>"Complete", :job_count=>3}]
uj5u.com熱心網友回復:
你可以像這樣用單行試試example_statuses.sort_by{|x| x[:status] == 'Pending' ? '' : x[:status] }
uj5u.com熱心網友回復:
order據我了解,您將獲得一個可以重新排序為等于的陣列
example_statuses.map { |h| h[:status] }
#=> ["Active", "Pending", "Complete"]
并且您希望排序example_statuses以產生一個陣列sorted,使得
sorted.map { |h| h[:status] } == order
#=> true
您不需要實際排序example_statues,這將具有 O( n*log(n)) 的計算復雜度,其中n等于 中的元素數example_statuses。
相反,請執行以下操作,其計算復雜度接近 O(· n)。認為
order = ["Pending", "Active", "Complete"]
案例1:g[:status] != h[:status]對于所有不同元素對g和hexample_statuses
在這種情況下計算
example_statuses.each_with_object({}) { |g,h| h[g[:status]] = g }
.values_at(*order)
#=> [{:status=>"Pending", :job_count=>1},
# {:status=>"Active", :job_count=>0},
# {:status=>"Complete", :job_count=>3}]
Hash#values_at的接收者如下所示。
example_statuses.each_with_object({}) { |g,h| h[g[:status]] = g }
#=> {"Active"=>{:status=>"Active", :job_count=>0},
# "Pending"=>{:status=>"Pending", :job_count=>1},
# "Complete"=>{:status=>"Complete", :job_count=>3}}
我之前聲稱計算復雜度“幾乎”為 O( n)。構建散列example_statuses.each_with_object({}) { |g,h| h[g[:status]] = g }是 O( n·),但每個元素的鍵查找或者order只是“幾乎”O(1)。如果是一個常數時間,復雜度將是 O(· n)。
案例 2:g[:status] == h[:status]對于至少一對不同的元素g和hexample_statuses
當然,這種情況可能是不允許的,但問題并沒有說明這一點。
假設order和以前一樣,但example_statuses如下。
example_statuses = [
{ :status => "Active", :job_count => 0 },
{ :status => "Pending", :job_count => 1},
{ :status => "Complete", :job_count => 3 },
{ :status => "Active", :job_count => 7 }
]
注意example_statuses[0][:status]andexample_statuses[3][:status]都相等"Active"。
我們只需要對案例 1 的計算稍作修改(這不會影響計算復雜度)。
example_statuses.each_with_object(Hash.new { |h,k| h[k] = [] }) do |g,h|
h[g[:status]] << g
end.values_at(*order).flatten
#=> [{:status=>"Pending", :job_count=>1},
# {:status=>"Active", :job_count=>0},
# {:status=>"Active", :job_count=>7},
# {:status=>"Complete", :job_count=>3}]
的接收者values_at被視為等于以下內容。
{"Active"=>[{:status=>"Active", :job_count=>0},
{:status=>"Active", :job_count=>7}],
"Pending"=>[{:status=>"Pending", :job_count=>1}],
"Complete"=>[{:status=>"Complete", :job_count=>3}]}
參見Hash::new的形式,它接受一個塊并且沒有引數。當h沒有鍵時,[g[:status]這會導致h[g[:status]]在執行之前分配給一個空陣列g[:status]<< g。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/463129.html
標籤:数组 红宝石 循环 ruby-on-rails-3 哈希
