【问题标题】:How to loop OpenStruct key/value pair如何循环 OpenStruct 键/值对
【发布时间】:2020-05-08 04:35:07
【问题描述】:

我有以下 OpenStruct 数据结构,我正在尝试获取键/值对

> #<OpenStruct conditions=[#<OpenStruct field="Out_of_country", operator="us", values=["true"]>, #<OpenStruct field="Status__c",
> operator="jp", values=["'Approved'"]>, #<OpenStruct field="Status__c",
> operator="gb", values=["'Rejected'"]>], conjunction="and">

Ruby 代码:

dataResult = nil
dataResult = data['condition'].include?('out_of_country']

这就是您从 OpenStruct 中提取键/值对的方式吗?

更新:

你说得对,我使用的是to_s,然后我删除了这就是我要访问的键/值

myresult = data['mainCondtion']
p myresult --> I got this result:

  > #<OpenStruct conditions=[#<OpenStruct field="Out_of_country", operator="us", values=["true"]>, #<OpenStruct field="Status__c",
    > operator="jp", values=["'Approved'"]>, #<OpenStruct field="Status__c",
    > operator="gb", values=["'Rejected'"]>], conjunction="and">

然后我尝试访问fieldvalues

myresult.each_pair{ |key, value| puts "#{key}: #{value}" }

我收到此错误:

# 的未定义方法“each_pair”

【问题讨论】:

  • 这与一个最小的可重现示例相去甚远。我们完全不知道data 是什么。
  • data 有一个更大的卡盘,它是一个 OpenStruct,我只过滤掉了 mainCondition,它是 data 的子集
  • 是的,但是如果您需要调试帮助,您必须向我们提供重现手头问题的示例和实际错误消息。我们不知道发生了什么,以及myresult = data['mainCondtion']myresult.each_pair 之间发生了什么。如果我们实际上无法复制您的代码并运行它,这只会导致一系列无休止的后续问题。

标签: ruby-on-rails ruby openstruct


【解决方案1】:

如果您只是想获取 OpenStruct 的单个属性,您只需对其调用 getter 方法:

country = OpenStruct(name: 'Japan', alpha_2: "jp", alpha_3: "jpn")
puts country.name # japan
puts country.alpha_3 # jpn

这就是 OpenStruct 的重点。您会得到一个行为类似于类实例的对象,而无需实际拥有类或不必像在普通 Struct 上那样提前定义属性。

您可以使用OpenStruct#each_pair 循环其属性,就像使用哈希一样:

os = OpenStruct.new a: 1, b: 2, c: 3
os.each_pair{ |key, value| puts "#{key}: #{value}" }
# Outputs:
# a: 1
# b: 2
# c: 3

【讨论】:

  • 我尝试对您在上面发布的OpenStruct 显示的示例执行相同的操作,但我收到了抱怨undefined method conditions for #&lt;string... 的错误
  • 好吧,对于初学者来说,你所拥有的都是字符串而不是 OpenStruct。我的猜测是你做了类似x = somevalue.inspectx = somevalue.to_s 的事情。不过,从您提供的详细信息中,我真的无法告诉您任何事情。
  • Max,我更新了我的问题,请看一下
【解决方案2】:

您正在尝试遍历哈希数组。

在 SO - How do I iterate over an array of hashes and return the values in a single string? 上查看此示例答案

@max 不喜欢我没有发布长篇解释,所以我将扩展我的上述答案。

irb(main):029:0> o = OpenStruct.new(foo: "bar", bar: "foo")
=> #<OpenStruct foo="bar", bar="foo">
irb(main):032:0> h = Hash.new
=> {}
irb(main):033:0> h[:foo] = "bar"
=> "bar"
irb(main):034:0> h[:bar] = "foo"
=> "foo"
irb(main):035:0> o
=> #<OpenStruct foo="bar", bar="foo">
irb(main):036:0> h
=> {:foo=>"bar", :bar=>"foo"}
irb(main):037:0> o.respond_to?(:each_pair)
=> true
irb(main):038:0> h.respond_to?(:each_pair)
=> true

OpenStructs 和 Hashes 都响应 @max 推荐的方法 - 使它们在您所描述的情况下在功能上没有什么不同。

irb(main):040:0> one = OpenStruct.new(field: "Out_of_country", operator: "us", values: ["true"])
=> #<OpenStruct field="Out_of_country", operator="us", values=["true"]>
irb(main):041:0> two = OpenStruct.new(field: "Out_of_country", operator: "jp", values: ["true"])
=> #<OpenStruct field="Out_of_country", operator="jp", values=["true"]>
irb(main):042:0> OpenStruct.new(conditions: [one, two])
=> #<OpenStruct conditions=[#<OpenStruct field="Out_of_country", operator="us", values=["true"]>, #<OpenStruct field="Out_of_country", operator="jp", values=["true"]>]>
irb(main):043:0> c = _
=> #<OpenStruct conditions=[#<OpenStruct field="Out_of_country", operator="us", values=["true"]>, #<OpenStruct field="Out_of_country", operator="jp", values=["true"]>]>
irb(main):044:0> hash_one = {field: "Out_of_country", operator: "us", values: ["true"]}
=> {:field=>"Out_of_country", :operator=>"us", :values=>["true"]}
irb(main):045:0> hash_two = {field: "Out_of_country", operator: "jp", values: ["true"]}
=> {:field=>"Out_of_country", :operator=>"jp", :values=>["true"]}
irb(main):046:0> hash_conditions = [hash_one, hash_two]
=> [{:field=>"Out_of_country", :operator=>"us", :values=>["true"]}, {:field=>"Out_of_country", :operator=>"jp", :values=>["true"]}]

irb(main):052:0> hash_conditions.each { |e| puts e[:operator] }
us
jp
=> [{:field=>"Out_of_country", :operator=>"us", :values=>["true"]}, {:field=>"Out_of_country", :operator=>"jp", :values=>["true"]}]
irb(main):053:0> c.conditions.each { |e| puts e[:operator] }
us
jp
=> [#<OpenStruct field="Out_of_country", operator="us", values=["true"]>, #<OpenStruct field="Out_of_country", operator="jp", values=["true"]>]

没有功能上的区别。

【讨论】:

  • OpenStruct 不是哈希。
  • @max 是的,但是你看到 Openstruct 和 hash 之间有什么区别吗?
  • @Rajagopalan 你在说什么?
  • @max 在功能上,为了做他想做的事,他可以把它当作循环哈希数组。当他试图实现的操作将以相同的方式实现时,说 OS != Hash 是迂腐的。您可以访问 OS 键值对与访问哈希键值对的方式完全相同。我的解释本来可以更清楚,但在功能上,对于发布的问题,没有区别。
  • 功能等同是夸大其词。您不必再看更远的OpenStruct#each 就可以找到一个差异很大的示例。 OpenStruct 有点像哈希,因为它定义了[][]=,但这确实是它的结束。
猜你喜欢
  • 2016-10-20
  • 2020-06-28
  • 2012-03-18
  • 1970-01-01
  • 2020-10-28
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
相关资源
最近更新 更多