【问题标题】:How to change hash return format for Ruby如何更改 Ruby 的哈希返回格式
【发布时间】:2020-07-26 19:23:15
【问题描述】:

我有以下哈希:

{"description":"Hello","id":"H"}`

如果我在控制台中输入哈希,我会得到:

{:description=>"Hello", :id=>"H"}

我希望它使用"description""id" 返回前面提到的相同表单。

有没有办法改变我的哈希返回的格式?

【问题讨论】:

  • 从技术上讲,是的,如果您覆盖 Hash 用于转储的方法,但不鼓励这样做,特别是如果其他人正在使用您的代码并期望默认输出。与其试图改变它,不如理解这两种形式是同义的。
  • 您是否尝试获取散列的 JSON 表示?如果是这样,请尝试hash.to_json。 (你可能需要require 'json'

标签: json ruby ruby-hash


【解决方案1】:
hash = {:description=>"HS - Hours", :id=>"HS"}

hash.stringify_keys
=> {"description"=>"HS - Hours", "id"=>"HS"}

【讨论】:

  • 这几乎是我想要的,但我需要将键和它们各自的值之间的分隔为分号,而不是箭头 =>
  • 你试图达到的结果看起来更像一个 json。您不能用分号分隔散列。试试 hash.to_json
  • 同意它看起来像 JSON。这可能是一个 XY 问题:“What is the XY problem?
  • 你能解释一下你到底要做什么以及为什么要这样做吗?
【解决方案2】:

用于提供对象的人类可读表示的方法是#inspect。这也是大多数 REPL 用来显示对象的方法,尽管一些 REPL 使用其他特定于 REPL 的方法,例如 #pretty_inspect

非常重要的是,所有这些方法仅供人类使用。您不得解析它们的输出,您不得将它们用于序列化、处理或任何其他操作,仅出于调试目的查看它们

所以,知道有问题的方法是Hash#inspect,您可以尝试覆盖该方法。请注意,不应该在生产代码中更改核心方法的行为。这是仅此答案的示例

module HashPrettyPrintExtension
  def inspect
    '{ ' <<
      map do |k, v|
        k = k.to_s if k.is_a?(Symbol)
        %Q[#{k.inspect}: #{v.inspect}]
      end.join(', ') <<
        ' }'
  end
end

module HashPrettyPrintRefinement
  refine Hash do
    prepend HashPrettyPrintExtension
  end
end

{ "description": "Hello", "id": "H" }
#=> { :description => "Hello", :id => "H" }

using HashPrettyPrintRefinement

{ "description": "Hello", "id": "H" }
#=> { "description": "Hello", "id": "H" }

请注意,您提出的输出有些限制。它确实只适用于 Symbols 的键和 Strings 的值,而在 Ruby 中,键可以是任意对象,值可以是任意对象。

此外,您提出的输出与#inspect 的目标完全相反,即提供人类可读的调试输出,因为不容易看出密钥不是字符串。

【讨论】:

    【解决方案3】:

    你有一个 HashSymbol 键:

    h = {"description": "Hello", "id": "H"}
    

    考虑一下

    ({"description": "Hello", "id": "H"}) == ({"description"=> "Hello", "id"=> "H"})
    #=> false
    
    ({"description": "Hello", "id": "H"}) == ({description: "Hello", id: "H"})
    #=> true
    

    Ruby 只是在打印时删除 "

    p ({"description":"Hello","id":"H"})
    #=> {:description=>"Hello", :id=>"H"}
    

    如果您想将密钥转换为String,您可以使用纯Ruby Hash#transform_keys(或bang 版本transform_keys!):

    h.transform_keys &:to_s
    #=> {"description"=>"Hello", "id"=>"H"}
    

    如果您正在寻找 json,请执行以下操作:

    require 'json'
    
    puts h.to_json
    #=> {"description":"Hello","id":"H"}
    

    还要考虑:

    h.to_json.class #=> String
    h.class #=> Hash
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-24
      • 2021-12-22
      • 2021-10-01
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      相关资源
      最近更新 更多