[英]Nested Hash from Two Arrays in Ruby + Sorting and Filtering by value
我是 Ruby 的新手,並且一直在嘗試使用我找到的所有資源和幾個 S/E 帖子來解決這個問題,但仍然無濟於事? 有人可以幫幫我嗎??
我有兩個簡單的 arrays,一個帶有標簽,另一個帶有相應的值。 這些是並行排序的,因此數組 1 的第 1 項映射到數組 2 的第 1 項。
假設我有這兩個 arrays:
labels = ["WinterLabel","SummerLabel","SpringLabel","FallLabel"]
values = [80,15,8,2]
我需要做的是 1) 過濾掉任何值大於 20 的對 2) 從最小值到最大值排序 3) 轉換為嵌套的 hash 結構,如下所示 - 不確定這是否是正確的順序任務,也許首先將其設為 hash,然后操作數據?-
outputhash = {
"name" => {
:label => "FallLabel",
:value => 2
},
"name2" => {
:label => "SpringLabel",
:value => 8
},
"name3" => {
:label => "SummerLabel",
:value => 15
}
}
name、name2、name3的具體名稱我無所謂,可以是從1開始的數字,也可以和label同名。
任何幫助或建議將不勝感激!
看看以下內容是否適合您:
labels = ["WinterLabel","SummerLabel","SpringLabel","FallLabel"]
values = [80,15,8,2]
output_hash = labels.map.with_index do |l, i|
{label: l, value: values[i]}
end.reject do |h|
h[:value] > 20
end.sort_by do |h|
h[:value]
end.each.with_object({}).with_index do|(h, memo), i|
memo[i+1] = h
end
建議,如果您對 hash 的主鍵是 label 沒問題,那么也許這對您更有效:
{"FallLabel"=>2, "SpringLabel"=>8, "SummerLabel"=>15, "WinterLabel"=>80}
然后,您可以執行以下操作:
output_hash = labels.map.with_index{|l, i| [l, values[i]]}.reject{|arr| arr[1] > 20}.sort_by(&:last).to_h
另外我不建議使用哈希來保存訂單信息
如果可能的話,盡量避免出現這種情況,而是使用對象來存儲數據,這畢竟是一種面向 object 的語言。 如果您將數據存儲在 class 中,例如:
# Forgive the poor class name...naming things is hard
class MyClass
include Comparable
attr_reader :label, :value
def initialize(label, value)
@label = label
@value = value
end
# required method for Comparable
def <=>(other)
value <=> other.value
end
def to_h
{ label: label, value: value }
end
end
那么你可以簡單地做(假設labels
包含一個MyClass
對象數組,它們具有與上面相同的數據):
labels.
select { |label| label.value < 20 }.
sort.
each_with_object({}) do |my_class, output_hash|
output_hash[my_class.label] = my_class.to_h
end
# => {"FallLabel"=>{:label=>"FallLabel", :value=>2},
# "SpringLabel"=>{:label=>"SpringLabel", :value=>8},
# "SummerLabel"=>{:label=>"SummerLabel", :value=>15}}
如果在 class 中包含Comparable
沒有意義(或者如果僅通過它們的值比較它們沒有意義),那么您可以將該sort
行替換為
sort_by(&:value).
達到同樣的效果。 如果重構為 class 超出了您的允許范圍,您可以將zip
數據放在一起並將它們視為 label 和值始終在同一個數組中
labels.zip(values)
# => [["WinterLabel", 80], ["SummerLabel", 15], ["SpringLabel", 8], ["FallLabel", 2]]
然后您可以從那里類似地對哈希進行排序和收集:
labels.zip(values).
select { |_, value| value < 20 }. # _ is ruby's conventional 'unused variable', meaning I don't care about the first value (the label) in each array
sort_by(&:last).
each_with_object({}) do |(label, value), output_hash|
output_hash[label] = { label: label, value: value }
end
# => {"FallLabel"=>{:label=>"FallLabel", :value=>2},
# "SpringLabel"=>{:label=>"SpringLabel", :value=>8},
# "SummerLabel"=>{:label=>"SummerLabel", :value=>15}}
核實
labels = ["WinterLabel","SummerLabel","SpringLabel","FallLabel"]
values = [80,15,8,2]
outputhash = {}
values.each_with_index do |d, i|
next if d > 20
outputhash["name#{i}"] ={ lable: labels[i], value: d }
end
outputhash = outputhash.sort_by{|a,b| b[:value] }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.