【问题标题】:Ruby how to format nested hashRuby如何格式化嵌套哈希
【发布时间】:2021-12-22 08:50:47
【问题描述】:

我有两个查询正在运行和迭代,我的最终哈希如下所示。但是,我想对数据如何存储在我正在创建的散列中或在我完成创建后格式化它进行格式化。但我不确定如何实现所需的格式,其中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

【问题讨论】:

  • 你是如何生成最终结果的?改变世代可能比事后重新格式化更有意义
  • @SaraFuerst 我正在迭代两组数据并以这种方式创建哈希。我更新了我的问题以包含逻辑
  • 什么是groups?您没有显示变量的来源。
  • 为什么需要pub_hash_truepub_hash_false?您的问题最初不是关于将数据分成“真/假”组,并且您没有显示是否/如何使用这些变量。
  • @TomLord 它在被控制器调用时作为一个哈希返回。我更新了我的问题,以显示组的来源。这是结果查询。 pub_hash_true 和 ``` pub_hash_false``` 是分开接受的:真/假值

标签: ruby-on-rails ruby hash


【解决方案1】:
# 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] }

【讨论】:

    【解决方案2】:

    您没有指定 desiredcurrent 格式之间的确切对应关系。 但我认为

    • 对于具有相同id的条目,acceptedtrans的值是相同的。
    • 当前格式中 Joe 的所需金额与 所需金额 中的相应金额相同。 (在您的示例中,前者是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 或任何格式化方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-05
      • 2021-03-16
      • 2019-02-21
      • 2019-08-08
      相关资源
      最近更新 更多