簡體   English   中英

從 Ruby 中的兩個 Arrays 嵌套 Hash + 按值排序和過濾

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM