Ruby 如何从数组中获取具有条件的数组数组
我有一个包含散列的数组,如下所示:Ruby 如何从数组中获取具有条件的数组数组,ruby,arrays,hash,Ruby,Arrays,Hash,我有一个包含散列的数组,如下所示: [ {:id => 1, :week => 1, :year => 2014}, {:id => 2, :week => 2, :year => 2014}, {:id => 1, :week => 1, :year => 2015}, {:id => 2, :week => 5, :year => 2015}, ] 我需要的是一个数组数组,每个数组包含两
[
{: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和week相等的散列,则第二个值必须为零,反之亦然,第一个值为零
对于上面的数组,新数组应该如下所示:
[
[{: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
result=[]
所有| id。每个都有| id|
每个星期都做|
v1=数组。选择{v | v.id==id&&v.week==week&&v.year==2014}
v2=数组。选择{v | v.id==id&&v.week==week&&v.year==2015}
v1=v1.length==1?v1.1:零
v2=v2.length==1?v1.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
这里有一种强调可读性的方法(认真地)
代码
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
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}]]
如果:year
的值可能不是2014
或2015
,则将a15=arr-a14
替换为:
a15 = arr.select { |h| h[:year] == 2015 }
请注意,a15.delete_at(i15)
具有双重功能:它从a15
中删除索引i15
处的值,并返回该值以包含在元组中
示例
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
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}]]
我更新了问题a.groupu的{| el |[el[:id],el[:week]}
可能是一个好方法。