Ruby 问一个整合数组 [Hash] 的方法

as181920 · April 22, 2013 · Last by as181920 replied at April 22, 2013 · 3041 hits
[
{entry_id: 1,field_id: 1, content: "x"},
{entry_id: 1,field_id: 2, content: "xx"},
{entry_id: 2,field_id: 1, content: "xxx"},
{entry_id: 2,field_id: 2, content: "xxxx"}
]

上面是原始数据,下面是目标结果

[
{entry_id: 1, data: {1: "x", 2: “xx”}},
{entry_id: 2, data: {1: "xxx", 2: "xxxx"}}
]

问怎么实现,想了半天头一直混混的,没想到方法,求指导,多谢。

ps:ruby + activerecord, 没有 rails,如果有需要可以加 gem

这也问 还 gem 呢..别在这里黑 Ruby 啦 您学点其他的去吧

#2 楼 @diga2005 你可以想象下等你老了干不动了,来了个壮年小伙把你一脚踹开的感觉:)

没想到方法的话,可以使用土方法啊,取值,然后赋值就好了

new_datas = {}
datas.each do |data|
  unless new_datas.key?(data[:entry_id])
    new_datas[data[:entry_id]] = {:data => {}}
  end
  new_datas[data[:entry_id]][:data].merge!({"field_#{data[:field_id]}" => data[:content]})
end

思路差不多就是这样了,自己改改

#3 楼 @as181920 问这种问题和年龄有关系哑?

datas.group_by { |hash| hash[:entry_id] }.map do |_, value|
  new_hash = {entry_id: value.first[:entry_id], data: Hash.new}
  value.each { |grouped_hash| new_hash[:data]["field_#{grouped_hash[:field_id]}"] = grouped_hash[:content] }
  new_hash
end

lz 你是真的懒啊。

#5 楼 @ywjno new_datas[data[:entry_id]] = {:data => {}}, 是{id: {data: {}}}三次嵌套,我是 2 层。等我清醒了我再看看,先多谢。

#8 楼 @as181920 那就改两个地方

# 。。。
new_datas[data[:entry_id]] = {:entry_id => data[:entry_id], :data => {}}
# 。。。

new_datas.values

用 group_by,map,inject

data.group_by{|e| e[:entry_id]}.map{|k, v| {:entry_id => k, :data => v.inject({}){|h, e| h.merge("field_#{e[:field_id]}".to_sym => e[:content])}}}

#10 楼 @quakewang 非常感谢,个人也有点单行的癖好哈,多谢多谢。

才发现我需求写的有问题,结果里面没有自定义字符,是 id 值,所以改了如下,结果 ok 了。

data.group_by{|e| e[:entry_id]}.map{|k, v| {:entry_id => k, :data => v.inject({}){|h, e| h.merge(e[:field_id] => e[:content])}}}

已解决,多谢楼上各位。感谢@zgm,@ywjno

其实我还是有点晕,等清醒了理理,平时对 inject 用的很不熟悉。多谢。

来个我的

h.group_by{|doc| doc[:entry_id]}.collect{|k,v| {entriy_id: k, data: v.collect{|v| v.reject{|k,v| k.eql? :entry_id}}}}

#12 楼 @jhjguxin 哎呀呀,海大爷都出来啦,平时请不动你,现在自己现身啦。

结果格式小有区别,都可以用,我好好学习,在挂在沙滩上之前再折腾折腾:)

You need to Sign in before reply, if you don't have an account, please Sign up first.