簡體   English   中英

Ruby 如何格式化嵌套哈希

[英]Ruby how to format nested hash

我有兩個查詢我正在運行並迭代這兩個查詢,我的最終哈希如下所示。 但是,我想對數據如何存儲在我創建的哈希中進行格式化,或者在創建完成后對其進行格式化。 但我不確定如何實現所需的格式,其中names與下面顯示的id相同

示例數據的所需格式:

[
    {
        id: 1,
        accepted: false,
        trans: 10234
        names: [
            { name: "Joe", amount: "$1,698.00" },
            { name: "Smith", amount: "$674.24" },
        ]
    },
    {
        id: 2,
        accepted: true,
        trans: 10234,
        names: [
            { name: "Joe", amount: "$1,698.00" },
            { name: "Smith", amount: "$674.24" },
        ]
    }
]

我的當前格式

[
    {
               :id => 1,
               :accepted => false,
               :trans => 8,
               :name => "Smith",
               :amount => 36.0
    },
    {
               :id => 1,
               :amount => false,
               :trans => 8,
               :name => "Joe",
               :amount => 6.0
    },
    {
               :id => 3,
               :accepted => false,
               :trans => 8,
               :name => "Tom",
               :amount => 34.0
    },
     {
               :id => 3,
               :accepted => false,
               :trans=> 8,
               :name => "Martha",
               :amount => 4.0
    }
], 
[
    {
               :id => 2,
               :accepted => true,
               :trans => 7,
               :name => "Bob",
               :amount => 35.0
    },
     {
                :id => 2,
                :accepted => true,
                :trans => 7,
                :name => "John",
                :amount => 5.0
    }
]

創建哈希的邏輯

imports = ListImports.limit(20).order(created_at: :DESC)
groups = imports.map{|import| ListImportGroup.where(list_import_id: import.id)}
pub_hash_true = []
pub_hash_false = []
hash = []
imports.map do |import|
  hash << {
     id: import.id,
     trans: import.trans,
     accepted: import.amount
  }
end
  hash.each do |import|
    groups.flatten.each do |group|
      accepted = import[:accepted]
      num_transactions = import[:trans]
      if accepted == false
        pub_hash_false << {id: import[:id], accepted: accepted, trans: num_transactions, name: group.name, amount: group.amount}
      else
        pub_hash_true << {id: import[:id], accepted: accepted, trans: num_transactions, name: group.name, amount: group.amount}
      end
    end
  end
# Note: You didn't specify what is the association between `ListImport` and `ListImportGroup`.
# However, I'm fairly sure you could be fetching this data via a JOIN query like below,
# rather than making up to 20 additional database calls to fetch the associated records.

imports = ListImports.limit(20).order(created_at: :DESC).includes(:list_import_group)

result = imports.map do |import|
  {
    id: import.id,
    trans: import.trans,
    accepted: import.amount,
    names: import.list_import_groups.pluck(:name, :amount)
  }
end

如果您確實需要過濾acceptedtruefalse導入,您可以執行以下操作,而不是手動構建單獨的數組:

accepted_imports = result.select { |import| import[:accepted] }
# and
rejected_imports = result.reject { |import| import[:accepted] }

# or even:
accepted_imports, rejected_imports = result.partition { |import| import[:accepted] }

您沒有指定所需格式和當前格式之間的確切對應關系。 但我假設

  • 對於具有相同id的條目, acceptedtrans的值是相同的。
  • 喬在當前格式所需的量在以期望相應的量相同。 (在您的示例中,前者是6.0而后者是"$1,698.00" ,這是沒有意義的。)

然后,以下將進行轉換。 數組ahout所需的格式。

 # Let us assume "a1" is the original array in the "current format"
hout = {}
a1.flatten.map{|h|
   h.slice(*(%i(id trans name amount accepted))).values
}.each{ |a|
  hout[a[0]] = {id: a[0], accepted: a[4], trans: a[1], names: []} if !hout.key? a[0]
  hout[a[0]][:names].push(
    {name: a[2], amount: "$"+helper.number_with_precision(a[3], precision: 2, delimiter: ',')}
  )
}

ahout = hout.values

如果您願意,您可能想對ahout進行排序。

請注意,我假設您使用的是 Rails 5+。 否則,方法helper可能無法工作。 在這種情況下,您可以使用sprintf或任何格式化方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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