2015-02-05 22 views
1

获得与条件数组的数组我有一个包含哈希值的数组,像这样:如何从一个数组

[ 
    {:id => 1, :week => 1, :year => 2014}, 
    {:id => 2, :week => 2, :year => 2014}, 
    {:id => 1, :week => 1, :year => 2015}, 
    {:id => 2, :week => 5, :year => 2015}, 
] 

我需要的是一个阵列阵列,包含每两个值: 第一个值来自2014年第一个数组的散列,第二个散列是2015年第一个数组的散列,如果它与第一个散列具有相同的星期和ID。

如果没有来自2015年的同等ID和星期的散列,那么第二个值必须为零,反之亦然,第一个值为零。

对于上面的数组,新数组应该是这样的:

[ 
    [{:id => 1, :week => 1, :year => 2014}, {:id => 1, :week => 1, :year => 2015}], 
    [{:id => 2, :week => 2, :year => 2014}, nil], 
    [nil, {:id => 2, :week => 5, :year => 2015}], 
] 

-E- 我的方法:

result = [] 
all_ids.each do |id| 
    all_weeks.each do |week| 
    v1 = array.select{ |v| v.id == id && v.week == week && v.year == 2014}   
    v2 = array.select{ |v| v.id == id && v.week == week && v.year == 2015} 
    v1 = v1.length == 1 ? v1.first : nil 
    v2 = v2.length == 1 ? v1.first : nil 
    result << [v1, v2] 
    end 

end 

这似乎不是很有效,因为我有多次迭代阵列

+0

我更新的问题 – 2015-02-05 13:48:51

+1

'a.group_by {| EL | [el [:id],el [:week]]}'可能是一个好方法。 – mudasobwa 2015-02-05 13:49:11

回答

1

使用group_by按星期和id分隔哈希,然后您只需填充没有两个值的数组:

array.group_by { |v| [v[:id], v[:week]] }.values.each do |a| 
    a.insert(2015 - a[0][:year], nil) if a.length == 1 
end 
+0

这就是我一直在寻找的,谢谢你! – 2015-02-05 16:07:14

0

这是一种旨在强调可读性(严重)的方式。

代码

def convert(arr) 
     a14 = arr.select { |h| h[:year] == 2014 } 
     a15 = arr - a14 
     arr = a14.map do |h14| 
     i15 = a15.index { |h15| h14[:id]==h15[:id] && h14[:week]==h15[:week] } 
     [ h14, i15.nil? ? nil : a15.delete_at(i15) ] 
     end 
     arr.concat([nil].product(a15)) if a15.any? 
    end 

如果:year值可以比20142015等,以代替a15 = arr - a14

a15 = arr.select { |h| h[:year] == 2015 } 

注意a15.delete_at(i15)具有双重功能:撤销值为i15,从a15开始,并返回包含在元组中的值。

arr = [ {:id => 1, :week => 1, :year => 2014}, 
     {:id => 2, :week => 2, :year => 2014}, 
     {:id => 1, :week => 1, :year => 2015}, 
     {:id => 2, :week => 5, :year => 2015} ] 

convert(arr) 
    #=> [[{:id=>1, :week=>1, :year=>2014}, {:id=>1, :week=>1, :year=>2015}], 
    # [{:id=>2, :week=>2, :year=>2014}, nil], 
    # [nil, {:id=>2, :week=>5, :year=>2015}]]