【发布时间】:2017-07-29 00:07:32
【问题描述】:
给定以下数据结构:
[
[:created_at, "07/28/2017"],
[:valid_record, "true"],
[:cs_details, { gender: 'm', race: 'w', language: nil } ],
[:co_details, { description: 'possess', extra: { a: 'a', b: 'b', c: 'c'} } ]
]
我想要一个键/值对数组:
[
[:created_at, "07/28/2017"],
[:valid_record, "true"],
[:gender, 'm'],
[:race, 'w'],
[:description, "process"]
[:a, "a"],
[:b, "b"],
[:c, "c"]
]
问题是我不知道如何展平这些哈希值。 flatten 什么都不做:
arr.map(&:flatten)
=> [[:created_at, "07/28/2017"], [:valid_record, "true"], [:cs_details, {:gender=>"m", :race=>"w", :language=>nil}], [:co_details, {:description=>"possess", :extra=>{:a=>"a", :b=>"b", :c=>"c"}}]]
所以我知道flat_map 也无济于事。我什至无法使用to_a 将这些哈希转换为数组:
arr.map(&:to_a)
=> [[:created_at, "07/28/2017"], [:valid_record, "true"], [:cs_details, {:gender=>"m", :race=>"w", :language=>nil}], [:co_details, {:description=>"possess", :extra=>{:a=>"a", :b=>"b", :c=>"c"}}]]
上述方法的问题在于它们仅适用于顶级索引。这些哈希值嵌套在数组中。所以我尝试减少,然后在结果上调用 flat_map:
arr.reduce([]) do |acc, (k,v)|
if v.is_a?(Hash)
acc << v.map(&:to_a)
else
acc << [k,v]
end
acc
end.flat_map(&:to_a)
=> [:created_at, "07/28/2017", :valid_record, "true", [:gender, "m"], [:race, "w"], [:language, nil], [:description, "possess"], [:extra, {:a=>"a", :b=>"b", :c=>"c"}]]
不完全在那里,但更接近。有什么建议吗?
【问题讨论】:
-
是否保证右边的参数要么是一个值,要么是一个Hash?
-
@Qwerp-Derp 是的
-
是否要排列所有嵌套的哈希?
-
是的,我只想要一个键/值对数组,就像我在问题的示例中所示。
-
旁注: 在这种情况下不要使用
reduce,使用each_with_object,后者不会在每次迭代时重新创建对象,而是在原地修改它,节省内存并且对冗余对象实例化没有任何惩罚。
标签: ruby