我有几乎是 的这段代码,可以给我我想要的东西。
def merge_data(keys, data)
merged_data = keys.map {|hash| data.first.map {|k,v| if hash.values.first == k then hash.merge(v) end}}
end
有关预期(第一个)和实际返回值之间的差异,请参见下文:
-[{:awesomeness=>10,
- :first_name=>"blake",
- :height=>"74",
- :last_name=>"johnson"},
- {:awesomeness=>9, :first_name=>"ashley", :height=>60, :last_name=>"dubs"}]
+[[{:awesomeness=>10,
+ :first_name=>"blake",
+ :height=>"74",
+ :last_name=>"johnson"},
+ nil],
+ [nil,
+ {:awesomeness=>9, :first_name=>"ashley", :height=>60, :last_name=>"dubs"}]]
如果有人可以解释为什么我得到的索引为nil的额外数组级别,将不胜感激!
基于以下数据:
let(:keys) {[
{:first_name => "blake"},
{:first_name => "ashley"}
]}
let(:data) {[
{"blake" => {
:awesomeness => 10,
:height => "74",
:last_name => "johnson"},
"ashley" => {
:awesomeness => 9,
:height => 60,
:last_name => "dubs"}
}
]}
let(:merged_data) {[
{:first_name => "blake",
:awesomeness => 10,
:height => "74",
:last_name => "johnson"},
{:first_name => "ashley",
:awesomeness => 9,
:height => 60,
:last_name => "dubs"}
]}
谢谢!
答案 0 :(得分:0)
您快到了,只需要进行微调:
def merge_data(keys, data)
merged_data = keys.map {|hash| data.first.map {|k,v| if hash.values.first == k then hash.merge(v) end }.compact[0] }
end
keys = [{:first_name => "blake"}, {:first_name => "ashley"}]
data = [
{"blake" => {
:awesomeness => 10,
:height => "74",
:last_name => "johnson"},
"ashley" => {
:awesomeness => 9,
:height => 60,
:last_name => "dubs"}
}]
puts merge_data(keys, data).inspect
#=>
[
{
:first_name=>"blake",
:awesomeness=>10,
:height=>"74",
:last_name=>"johnson"},
{
:first_name=>"ashley",
:awesomeness=>9,
:height=>60,
:last_name=>"dubs"
}
]
更改了什么?
在内部块中添加了.compact[0]
。
为什么?因为它是在每个键和每个数据值上运行的map
。对于与另一个不匹配的一个返回nil,并且每次返回一个数组而不是Hash
对象。
但是,我们可以创建一个自定义类并在以后重建数据:
class Person
attr_reader :first_name, :last_name, :height, :awesomeness
def initialize(first_name)
@first_name = first_name
end
def update(info)
info.each do |key, value|
instance_variable_set("@#{key}", value) if respond_to?(key)
end
end
def to_h
{ first_name: self.first_name, last_name: self.last_name, awesomeness: self.awesomeness, height: self.height }
end
end
people = keys.each_with_object({}) do |k, person_map|
person_map[k[:first_name]] = Person.new(k[:first_name])
end
data.each do |people_info|
people_info.each do |first_name, info|
if people[first_name]
people[first_name].update(info)
end
end
end
p people.values.map{ |p| p.to_h }
#=> [{:first_name=>"blake", :last_name=>"johnson", :awesomeness=>10, :height=>"74"}, {:first_name=>"ashley", :last_name=>"dubs", :awesomeness=>9, :height=>60}]
答案 1 :(得分:0)
给出数据集:
data = {
"blake" => {
:awesomeness => 10,
:height => "74",
:last_name => "johnson"},
"ashley" => {
:awesomeness => 9,
:height => 60,
:last_name => "dubs"}
}
为什么不像这样?
data.map { |h| h.last.merge({first_name: h.first}) }
#=> [{:awesomeness=>10, :height=>"74", :last_name=>"johnson", :first_name=>"blake"}, {:awesomeness=>9, :height=>60, :last_name=>"dubs", :first_name=>"ashley"}]
因此,如果我很了解您的数据结构,请尝试Enumerable#each_with_object:
def merge_data(keys, data)
keys.each_with_object([]) { |hash, obj| data.first.map { |k,v| if hash.values.first == k then obj << hash.merge(v) end } }
end
keys = [
{:first_name => "blake"},
{:first_name => "ashley"}
]
data = [{
"blake" => {
:awesomeness => 10,
:height => "74",
:last_name => "johnson"},
"ashley" => {
:awesomeness => 9,
:height => 60,
:last_name => "dubs"}
}]
merge_data(keys, data)
#=> [{:first_name=>"blake", :awesomeness=>10, :height=>"74", :last_name=>"johnson"}, {:first_name=>"ashley", :awesomeness=>9, :height=>60, :last_name=>"dubs"}]
答案 2 :(得分:0)
keys = [{ :first_name=> "ashley" }, { :first_name=>"blake" }]
data = [{ "blake" => { :awesomeness=>10, :height=>"74", :last_name=>"johnson" },
"margo" => { :awesomeness=>30, :height=>"63", :last_name=>"magpie" },
"ashley" => { :awesomeness=>9, :height=>"60", :last_name=>"dubs" } }]
我建议分两个步骤进行。首先是为data
的内容构造一个更合适的数据结构,即哈希:
data_adj = data.reduce(&:merge)
#=> {"blake" =>{:awesomeness=>10, :height=>"74", :last_name=>"johnson"},
# "margo" =>{:awesomeness=>30, :height=>"63", :last_name=>"magpie"},
# "ashley"=>{:awesomeness=>9, :height=>"60", :last_name=>"dubs"}}
第二个方法是将keys
中的哈希值与data_adj
的适当值合并:
keys.map { |h| h.merge(data_adj[h[:first_name]]) }
#=> [{:first_name=>"ashley", :awesomeness=>9, :height=>"60", :last_name=>"dubs"},
# {:first_name=>"blake", :awesomeness=>10, :height=>"74", :last_name=>"johnson"}]
如果要针对keys
的不同值重复执行合并操作,则此方法将特别有效,因为data_adj
仅需要计算一次。将问题分为两个也可以加快测试速度。