ruby 将哈希转换为结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11962192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert a hash into a struct
提问by alf
How can I convert a hash into a struct in ruby?
如何将散列转换为 ruby 中的结构?
Given this:
鉴于这种:
h = { :a => 1, :b => 2 }
I want a struct such that:
我想要一个这样的结构:
s.a == 1
s.b == 2
回答by elado
If you already have a struct defined, and you want to instantiate an instance with a hash:
如果您已经定义了一个结构,并且您想用散列实例化一个实例:
Person = Struct.new(:first_name, :last_name, :age)
person_hash = { first_name: "Foo", last_name: "Bar", age: 29 }
person = Person.new(*person_hash.values_at(*Person.members))
=> #<struct Person first_name="Foo", last_name="Bar", age=29>
回答by Dave Newton
If it doesn't specificallyhave to be a Structand instead can be an OpenStruct:
如果它不是特别必须是 aStruct而是可以是OpenStruct:
pry(main)> require 'ostruct'
pry(main)> s = OpenStruct.new(h)
=> #<OpenStruct a=1, b=2>
pry(main)> puts s.a, s.b
1
2
回答by Phrogz
Since Hash key order is guaranteed in Ruby 1.9+:
由于哈希键顺序在 Ruby 1.9+ 中得到保证:
Struct.new(*h.keys).new(*h.values)
回答by alf
The following creates a struct from a hash in a reliable way (since hash order is not guaranteed in ruby):
以下以可靠的方式从散列创建一个结构(因为在 ruby 中不保证散列顺序):
s = Struct.new(*(k = h.keys)).new(*h.values_at(*k))
回答by Dorian
Having Hash#to_structis quite practical:
有Hash#to_struct很实用:
class Hash
def to_struct
Struct.new(*keys).new(*values)
end
end
And some examples:
还有一些例子:
>> { a: 1, b: 2 }.to_struct
=> #<struct a=1, b=2>
>> { a: 1, b: 2 }.to_struct.a
=> 1
>> { a: 1, b: 2 }.to_struct.b
=> 2
>> { a: 1, b: 2 }.to_struct.c
NoMethodError: undefined method `c` for #<struct a=1, b=2>
Deep to_structthat works with arrays:
to_struct与数组一起使用的深度:
class Array
def to_struct
map { |value| value.respond_to?(:to_struct) ? value.to_struct : value }
end
end
class Hash
def to_struct
Struct.new(*keys).new(*values.to_struct)
end
end
回答by 8bithero
This is based on @elado's answer above, but using the keyword_initvalue (Struct Documentation)
这是基于@elado 上面的回答,但使用keyword_init值(结构文档)
You could simply do this:
你可以简单地这样做:
Person = Struct.new(:first_name, :last_name, :age, keyword_init: true)
person_hash = { first_name: "Foo", last_name: "Bar", age: 29 }
person = Person.new(person_hash)
=> #<struct Person first_name="Foo", last_name="Bar", age=29>
回答by Dino Reic
This gives a clean plain read-only object, similar to a ruby Struct but with deep conversion and extra to_hmethod to get struct at any point as Hash.
这提供了一个干净的普通只读对象,类似于 ruby Struct,但具有深度转换和额外的to_h方法来在任何时候将 struct 作为 Hash 获取。
Example
例子
foo = {a:{b:{c:123}}}.to_struct
foo.a.b.c # 123
foo.a.to_h # {b:{c:123}}
Ruby code
红宝石代码
class Hash
def to_struct
Class.new.tap do |c|
c.define_singleton_method(:to_h) do
m_list = methods(false) - [:to_h]
m_list.inject({}) do |h, m|
h[m] = send(m)
h[m] = h[m].to_h if h[m].class == Class
h
end
end
each do |k, v|
v = v.to_struct if v.class == Hash
c.define_singleton_method(k) { v }
end
end
end
end
Not exactly the answer to a question (not a ruby Struct object), but I needed just this while looking for an answer, so I will just post the answer here.
不完全是问题的答案(不是 ruby Struct 对象),但我在寻找答案时只需要这个,所以我将在这里发布答案。
回答by 6ft Dan
Here's an example to map the values to the proper order of the Struct:
这是将值映射到结构的正确顺序的示例:
require 'securerandom'
Message = Struct.new(:to, :from, :message, :invitee)
message_params = {from: "[email protected]", to: "[email protected]",
invitee: SecureRandom.uuid, message: "hello"}
if Message.members.sort == message_params.keys.sort
# Do something with the return struct object here
Message.new *Message.members.map {|k| message_params[k] }
else
raise "Invalid keys for Message"
end
回答by nardele salomon
require 'ds_hash'
data = {a: {b: 123 }}.to_struct
data.a.b == 123 # true
data.a == {b: 123 } # true

