2015-01-26 49 views
0

鉴于阵列分组散列的数组优化日期

[ 
    {date: '2014-01-01', a: 5, b:1}, 
    {date: '2014-01-01', xyz: 11}, 
    {date: '2014-10-10', qbz: 5}, 
    {date: '2014-10-10', v: 4, q: 1, strpm: -99} 
] 

我想按日期和输出哈希

ouput = [ 
{date: 2014-01-01, a: 5, b:1, xyz: 11 }, 
{date: 2014-10-10, qbz: 5, v: 4, q: 1, strpm: -99}, 
] 

我解决它在Ruby中的数组,并有一个解决方案,但它似乎效率低下。

def arrayt(inputarray) 
    outputarray=[]; 
    inputarray.each do |x| 
     tindex = includes(outputarray,x[:date]) 
     if tindex == -1 
      outputarray.push(x) 
     else 
      outputarray[tindex].merge!(x) 
     end 
    end 
    return outputarray 
end 

def includes(array,date) 
    array.each_with_index do |temp,index| 
     if date==temp[:date] 
      return index 
     end 
    end 
    return -1 
end 

具有更优雅的解决方案的任何帮助,将不胜感激

+0

不知道你是否可以在ruby中做到这一点,但如果你可以使用每个数组元素的第一个元素作为散列(或字典)键,然后将其后的任何内容附加到该散列槽。 – Abbath 2015-01-26 22:13:54

+0

使用'group_by'然后得到'.values' – Phrogz 2015-01-26 22:14:02

+1

可能更适合Code Review。 – cybermonkey 2015-01-26 22:17:29

回答

6
[ 
    {date: '2014-01-01', a: 5, b:1}, 
    {date: '2014-01-01', xyz: 11}, 
    {date: '2014-10-10', qbz: 5}, 
    {date: '2014-10-10', v: 4, q: 1, strpm: -99} 
] 
.group_by(&:first).map{|_, v| v.inject(:merge)} 
+0

你能解释一下代码吗? – BMW 2015-01-27 06:00:54

2

下面是使用的Hash#update(又名merge!)的形式,它使用一个块,以确定所存在的键的值的方式在这两个哈希值被合并:

arr.each_with_object({}) { |g,h| 
    h.update({ g[:date]=>g }) { |_,ov,nv| ov.merge(nv) } }.values 

机智:

hash = arr.each_with_object({}) { |g,h| 
     h.update({ g[:date]=>g }) { |_,ov,nv| ov.merge(nv) } } 
    #=>{"2014-01-01"=>{:date=>"2014-01-01", :a=>5, :b=>1, :xyz=>11}, 
    # "2014-10-10"=>{:date=>"2014-10-10", :qbz=>5, :v=>4, :q=>1, :strpm=>-99}} 
    hash.values 
    #=> [{:date=>"2014-01-01", :a=>5, :b=>1, :xyz=>11}, 
    # {:date=>"2014-10-10", :qbz=>5, :v=>4, :q=>1, :strpm=>-99}]