处理嵌套哈希以将所有值转换为字符串 [英] Process nested hash to convert all values to strings

查看:120
本文介绍了处理嵌套哈希以将所有值转换为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的代码,它接受一个散列并将所有转换为字符串。

  def stringify_values obj 
@values || = obj.clone

obj.each do | k,v |
如果v.is_a?(哈希)
@values [k] = stringify_values(v)
else
@values [k] = v.to_s
end
end

return @values
end

所以给出以下散列:

  {
发布:{
id:123,
text :'foobar',
}
}

YAML 输出

  ---& 1 
:post:* 1
: id:'123'
:text:'foobar'

当我想要输出

  --- 
:发布:
:id:'123'
:text: 'foobar'

看起来对象已经变平,然后被赋予了一个参考,导致堆栈级别错误在我的规格。



我如何得到所需的输出?

解决方案

一个简单的 stringify_values 可以 - 假设它总是一个哈希。此函数使用 Hash#deep_merge 方法由Active Support Core Extensions添加 - 我们将散列与自身合并,以便在块中检查每个值并在其上调用 to_s

  def stringify_values obj 
obj.deep_merge(obj){| _,_,v | v.to_s}
end






完成工作示例:

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b def stringify_values obj
obj.deep_merge(obj){| _,_,v | v.to_s}
end

class Foo
def to_s
I am Foo
end
end

h = {
post:{
id:123,
arr:[1,2,3],
text:'foobar',
obj:{ me:Foo.new}
}
}

puts YAML.dump(stringify_values h)
#=>
---
:post:
:id:'123'
:arr:[1,2,3]
:text:foobar
:obj:
:me:我是Foo

不知道期望值是多少当value是一个数组时,作为 Array#to_s 也会给你一个字符串,无论这是否合意,你可以决定并稍微调整一下解决方案。

I have the following code which takes a hash and turns all the values in to strings.

def stringify_values obj
  @values ||= obj.clone

  obj.each do |k, v|
    if v.is_a?(Hash)
      @values[k] = stringify_values(v)
    else
      @values[k] = v.to_s
    end
  end

  return @values
end

So given the following hash:

{
  post: {
    id: 123,
    text: 'foobar',
  }
}

I get following YAML output

--- &1
:post: *1
:id: '123'
:text: 'foobar'

When I want this output

--- 
:post: 
  :id: '123'
  :text: 'foobar'

It looks like the object has been flattened and then been given a reference to itself, which causes Stack level errors in my specs.

How do I get the desired output?

解决方案

A simpler implementation of stringify_values can be - assuming that it is always a Hash. This function makes use of Hash#deep_merge method added by Active Support Core Extensions - we merge the hash with itself, so that in the block we get to inspect each value and call to_s on it.

def stringify_values obj
  obj.deep_merge(obj) {|_,_,v| v.to_s}
end


Complete working sample:

require "yaml"
require "active_support/core_ext/hash"

def stringify_values obj
  obj.deep_merge(obj) {|_,_,v| v.to_s}
end

class Foo
    def to_s
        "I am Foo"
    end
end

h = {
  post: {
    id: 123,
    arr: [1,2,3],
    text: 'foobar',
    obj: { me: Foo.new}
  }
}

puts YAML.dump (stringify_values h)
#=> 
---
:post:
  :id: '123'
  :arr: "[1, 2, 3]"
  :text: foobar
  :obj:
    :me: I am Foo

Not sure what is the expectation when value is an array, as Array#to_s will give you array as a string as well, whether that is desirable or not, you can decide and tweak the solution a bit.

这篇关于处理嵌套哈希以将所有值转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆