有更好的方法吗? 我有两个哈希数组,我希望得到一个哈希数组,其中天数重叠,版本设置为交集(即版本1_for_arr1&& version1_for_arr2)。
arr1是
[{:day=>day1, :version1=>true, :version2=>false, :version3=>true},
{:day=>day3, :version1=>false, :version2=>false, :version3=>true},
{:day=>day4, :version1=>true, :version2=>false, :version3=>false},
{:day=>day5, :version1=>true, :version2=>true, :version3=>true},
{:day=>day10, :version1=>true, :version2=>true, :version3=>true},
{:day=>day15, :version1=>true, :version2=>false, :version3=>false}]
arr2是
[{:day=>day1, :version1=>false, :version2=>false, :version3=>true},
{:day=>day2, :version1=>false, :version2=>false, :version3=>true},
{:day=>day4, :version1=>true, :version2=>true, :version3=>false},
{:day=>day5, :version1=>false, :version2=>true, :version3=>true},
{:day=>day15, :version1=>true, :version2=>false, :version3=>false}]
在这种情况下,最终的数组将是:
[{:day=>day1, :version1=>false, :version2=>false, :version3=>true},
{:day=>day4, :version1=>true, :version2=>false, :version3=>false},
{:day=>day5, :version1=>false, :version2=>true, :version3=>true},
{:day=>day15, :version1=>true, :version2=>false, :version3=>false}]
我能想到的唯一方法就是嵌套迭代,即
days=[]
arr1.each do |d1|
arr2.each do |d2|
if d1[:day]==d2[:day]
days<<Hash.new(:day=>d1, :version1=>(d1[:version1]&&d2[:version1], :version2=>(d1[:version2]&&d2[:version2], :version3=>(d1[:version3]&&d2[:version3])
end
end
end
然而,当它被缩放并且数组变得非常大时,这看起来非常昂贵。它迭代n ^ n次。
我确实在rassoc和assoc上看到了http://rosettacode.org/wiki/Loop_over_multiple_arrays_simultaneously#Ruby,但看起来它们需要是数组中的数组,后来我将生成的哈希用作哈希。
有更好的方法吗?我不断提出其他想法,但当我真正检查它们时,它们都会回到两次嵌套迭代。
答案 0 :(得分:1)
你从哪里得到这两个哈希数组?如果您将搜索词存储在SQL数据库中,这似乎是您可以使用查询执行的操作。
否则,您可能会考虑使用Set来查找日期的交集。
require 'set'
def daylist(arr)
arr.map { |a| a[:day] }
end
set1 = Set.new(daylist(arr1))
set2 = Set.new(daylist(arr2))
days = set1.intersection(set2)
result = ....
我停在那里因为我正在进一步查看你的数据,我想知道你是否可以重组它。我觉得它可以更容易转换,如果不是哈希数组,你做一个数组的哈希:
require 'set'
h1 = {
day1: [ true, false, true ],
day3: [ false, false, true ],
day4: [ true, false, false ],
day5: [ true, true, true ],
day10: [ true, true, true ],
day15: [ true, false, false ]
}
h2 = {
day1: [ false, false, true ],
day2: [ false, false, true ],
day4: [ true, true, false ],
day5: [ false, true, true ],
day15: [ true, false, false ]
}
# Intersect them.
set1 = Set.new(h1.keys)
set2 = Set.new(h2.keys)
intersection = set1.intersection(set2)
# Compute the lval & rval arrays
anded = intersection.map do |day|
h1[day].each_with_index.map { |x, i| x && h2[day][i] }
end
# Convert them back into a Hash like our originals
final = Hash[intersection.zip(anded)]
当然,如果这些东西来自Postgres或其他东西,那么你最好不要在查询中尝试这样做。在那种情况下,我刚写的所有东西对你都没用。 ;)