我正在尝试获取包含ID位置的两个哈希数组,并返回位置更改。数据来自不同日期的图表。
如果2018-01-01的图表1包含:
[
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800002"},
{:position=>3, :id=>"GBMMV1800003"}
]
和2018-01-07的图表2包含:
[
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800003"},
{:position=>3, :id=>"GBMMV1800002"}
]
如何生成显示位置变化的结果?
[
{:position=>1, :id=>"GBMMV1800001", :change=>0},
{:position=>2, :id=>"GBMMV1800003", :change=>1},
{:position=>3, :id=>"GBMMV1800002", :change=>-1}
]
答案 0 :(得分:2)
假设没有重复的id
s:
in1 = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800002"},
{:position=>3, :id=>"GBMMV1800003"}
]
in2 = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800003"},
{:position=>3, :id=>"GBMMV1800002"}
]
[in1, in2].map do |a|
a.group_by { |h| h[:id] }
end.reduce do |h1, h2|
h1.merge(h2) do |k, v1, v2|
v2.first.merge(change: v1.first[:position] - v2.first[:position])
end
end.values.sort_by { |h| h[:position] }
#⇒ [{:position=>1, :id=>"GBMMV1800001", :change=>0},
# {:position=>2, :id=>"GBMMV1800003", :change=>1},
# {:position=>3, :id=>"GBMMV1800002", :change=>-1}]
答案 1 :(得分:1)
chart1 = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800002"},
{:position=>3, :id=>"GBMMV1800003"}
]
chart2 = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800003"},
{:position=>3, :id=>"GBMMV1800002"}
]
h = chart1.each_with_index.with_object({}) { |(g,i),h| h[g[:id]] = i }
#=> {"GBMMV1800001"=>0, "GBMMV1800002"=>1, "GBMMV1800003"=>2}
chart2.each_with_index.map { |g,i| g.merge(change: h[g[:id]] - i) }
#=> [{:position=>1, :id=>"GBMMV1800001", :change=>0},
# {:position=>2, :id=>"GBMMV1800003", :change=>1},
# {:position=>3, :id=>"GBMMV1800002", :change=>-1}]
答案 2 :(得分:0)
鉴于
h1 = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800002"},
{:position=>3, :id=>"GBMMV1800003"}
]
h2 = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800003"},
{:position=>3, :id=>"GBMMV1800002"}
]
我想要一张{ id => [position1, position2] }
的地图。
首先,我遍历h1以获得其位置
vals = {}
h1.each do |val|
vals[val[:id]] = [val[:position]]
end
现在vals等于
{
"GBMMV1800001" => [1],
"GBMMV1800002" => [2],
"GBMMV1800003" => [3]
}
然后我遍历第二个数组,添加其位置。
h2.each do |val|
# This will ignore ids that aren't present in h1
next unless vals[val[:id]]
vals[val[:id]].push val[:position]
end
现在我拥有了计算差异所需的所有数据:
{
"GBMMV1800001" => [1, 1],
"GBMMV1800002" => [2, 3],
"GBMMV1800003" => [3, 2]
}
要获得差异,我会使用transform_values
与ruby 2.4或主动支持一起使用。顺便说一下,您也可以使用reduce
或each_with_object
。
diffs = vals.transform_values { |(pos1, pos2)| pos2 - pos1 }
这会在块参数中使用destructuring。
答案 3 :(得分:0)
这似乎可以解决问题
def get_position_changes array0, array1
array1.map.with_index do |hash1, index|
new_hash = hash1.dup
new_hash[:change] = array0.index {|hash0| hash0[:id] == hash1[:id]} - index
new_hash
end
end
first_array = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800002"},
{:position=>3, :id=>"GBMMV1800003"}
]
second_array = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800003"},
{:position=>3, :id=>"GBMMV1800002"}
]
p get_position_changes(first_array, second_array)
#=> [
#=> {:position=>1, :id=>"GBMMV1800001", :change=>0}
#=> {:position=>2, :id=>"GBMMV1800003", :change=>1}
#=> {:position=>3, :id=>"GBMMV1800002", :change=>-1}
#=> ]
答案 4 :(得分:0)
您开始使用的结构:
h1 = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800002"},
{:position=>3, :id=>"GBMMV1800003"}
]
h2 = [
{:position=>1, :id=>"GBMMV1800001"},
{:position=>2, :id=>"GBMMV1800003"},
{:position=>3, :id=>"GBMMV1800002"}
]
不合适。你应该开始使用以下结构:
a1 = h1.map{|h| h[:id]} # => ["GBMMV1800001", "GBMMV1800002", "GBMMV1800003"]
a2 = h2.map{|h| h[:id]} # => ["GBMMV1800001", "GBMMV1800003", "GBMMV1800002"]
如上所述,
b1 = a1.map.with_index(1).to_h
# => {"GBMMV1800001"=>1, "GBMMV1800002"=>2, "GBMMV1800003"=>3}
b2 = a2.map.with_index(1).to_h
# => {"GBMMV1800001"=>1, "GBMMV1800003"=>2, "GBMMV1800002"=>3}
b1.keys.map{|k| {id: k, position: b1[k], change: b2[k] - b1[k]}}
# => [
# {:id=>"GBMMV1800001", :position=>1, :change=>0},
# {:id=>"GBMMV1800002", :position=>2, :change=>1},
# {:id=>"GBMMV1800003", :position=>3, :change=>-1}
# ]