我有一系列的散列
a = [
{start_time: 9am, end_time: 10am},
{start_time: 10am, end_time: 11am},
{start_time: 11am, end_time: 12am},
{start_time: 1pm, end_time: 2pm},
{start_time: 2pm, end_time: 3pm},
{start_time: 3pm, end_time: 4pm},
{start_time: 4pm, end_time: 5pm},
{start_time: 5pm, end_time: 6pm}
]和另一组日期范围和优先级-1是最高优先级。
p = [
{start_time: 11am, end_time: 3pm, priority: 1},
{start_time: 2pm, end_time: 5pm, priority: 2},
{start_time: 9am, end_time: 6m, priority: 3}
]因此,如果将其应用于前面的数组
a = [
{start_time: 9am, end_time: 10am}, #has priority 3
{start_time: 10am, end_time: 11am}, #has priority 3
{start_time: 11am, end_time: 12am}, #has priority 3 & 1
{start_time: 1pm, end_time: 2pm}, #has priority 3 & 1
{start_time: 2pm, end_time: 3pm}, #has priority 3 & 2 & 1
{start_time: 3pm, end_time: 4pm}, #has priority 3 & 2
{start_time: 4pm, end_time: 5pm}, #has priority 3 & 2
{start_time: 5pm, end_time: 6pm} #has priority 3
]我想根据优先级在每个范围内分割数组。因此,步骤1将在优先级1处分割数组:
a = [
{start_time: 9am, end_time: 10am},
{start_time: 10am, end_time: 11am},
[{start_time: 11am, end_time: 12am}, #priority 1
{start_time: 1pm, end_time: 2pm}, #priority 1
{start_time: 2pm, end_time: 3pm}], #priority 1
{start_time: 3pm, end_time: 4pm},
{start_time: 4pm, end_time: 5pm},
{start_time: 5pm, end_time: 6pm}
]优先级2不能在它的起始点被分割,因为它是由优先级1所拥有的。所以取最早的可用起点:
a = [
{start_time: 9am, end_time: 10am},
{start_time: 10am, end_time: 11am},
[{start_time: 11am, end_time: 12am}, #priority 1
{start_time: 1pm, end_time: 2pm}, #priority 1
{start_time: 2pm, end_time: 3pm}], #priority 1
[{start_time: 3pm, end_time: 4pm}, #priority 2
{start_time: 4pm, end_time: 5pm}], #priority 2
{start_time: 5pm, end_time: 6pm}
]其余部分将成为优先级3,如果start_time与之前的end_time不匹配,我希望拆分数组。所以我想要的最后结果是:
a = [
[{start_time: 9am, end_time: 10am}, #priority 3
{start_time: 10am, end_time: 11am}], #priority 3
[{start_time: 11am, end_time: 12am}], #priority 1 - note times aren't consecutive here
[{start_time: 1pm, end_time: 2pm}, #priority 1
{start_time: 2pm, end_time: 3pm}], #priority 1
[{start_time: 3pm, end_time: 4pm}, #priority 2
{start_time: 4pm, end_time: 5pm}], #priority 2
[{start_time: 5pm, end_time: 6pm}] #priority 3
]我试图为此建立一个算法。它基本上按照顺序遍历每个优先级,从范围中选择并将其移动到一个新的数组中。
p_blocks = []
p.sort_by! { |x| x.[:priority] }
p.each do |block|
f = getReach(a, block[:start_time], block[:end_time])
f = x.slice_when { |x, y| x[:end_time] != y[:start_time]}.to_a if f.length > 0
p_blocks << f.flatten
a-f # remove from array
end
return p_blocks
def getReach(logs, start_time, end_time)
reach = logs.select { |time_log| # get all logs within range
((time_log[:start_time] < end_time and time_log[:start_time] > start_time) or
(time_log[:end_time] > start_time and time_log[:end_time] < end_time))
}.sort_by! { |x| x[:start_time] }
return reach
end然而,它不起作用,当我不需要的时候,我可能会把事情弄平,而且对于大数据集,它可能会很慢。
如果你能提供任何帮助那就太棒了。
发布于 2015-04-03 01:18:16
试试这个:
a = [{:start_time=>9, :end_time=>10}, {:start_time=>10, :end_time=>11}, {:start_time=>11, :end_time=>12}, {:start_time=>13, :end_time=>14}, {:start_time=>14, :end_time=>15}, {:start_time=>15, :end_time=>16}, {:start_time=>16, :end_time=>17}, {:start_time=>17, :end_time=>18}]
p = [{start_time: 11, end_time: 3+12, priority: 1},
{start_time: 2+12, end_time: 5+12, priority: 2},
{start_time: 9, end_time: 6+12, priority: 3}
]
p.each {|i| a.each {|j| j[:priority] = i[:priority] if (j[:priority].nil?) && (i[:start_time]..i[:end_time]).include?(j[:start_time]) && (i[:start_time]..i[:end_time]).include?(j[:end_time])}}
a输出:
# => [{:start_time=>9, :end_time=>10, :priority=>3}, {:start_time=>10, :end_time=>11, :priority=>3}, {:start_time=>11, :end_time=>12, :priority=>1}, {:start_time=>13, :end_time=>14, :priority=>1}, {:start_time=>14, :end_time=>15, :priority=>1}, {:start_time=>15, :end_time=>16, :priority=>2}, {:start_time=>16, :end_time=>17, :priority=>2}, {:start_time=>17, :end_time=>18, :priority=>3}] 希望您能处理把上午/下午转换为24小时格式。
发布于 2015-04-03 06:38:02
这只是一个部分的答案。我将建议您如何将优先级添加到a中,然后分割为优先级1。除此之外,我不明白你在做什么,你的最终目标是什么。如果问题得到澄清,我也许可以阐述一些。
虽然我将只回答部分您的问题,但我认为我有一些有用的东西可以用来说明数据结构、代码组织和执行一些您需要做的计算的技术。
重新组织数据并创建辅助方法
首先,让我们把a放在更方便的形式上。请注意,您需要在引号中显示时间:
a = [
{start_time: "9am", end_time: "10am"},
{start_time: "10am", end_time: "11am"},
{start_time: "11am", end_time: "12am"},
{start_time: "1pm", end_time: "2pm"},
{start_time: "2pm", end_time: "3pm"},
{start_time: "3pm", end_time: "4pm"},
{start_time: "4pm", end_time: "5pm"},
{start_time: "5pm", end_time: "6pm"}
]用于执行此操作的两个助手方法:
def convert(str)
str.to_i + ((str[-2]=='p') ? 12 : 0)
end
def change(h)
{ interval: convert(h[:start_time])..convert(h[:end_time]) }
end现在,让我们将a转换为一种更易于使用的结构(而不改变a):
b = a.each_with_object([]) { |h,a| a << change(h) }
#=> [{:interval=> 9..10}, {:interval=>10..11}, {:interval=>11..12},
# {:interval=>13..14}, {:interval=>14..15}, {:interval=>15..16},
# {:interval=>16..17}, {:interval=>17..18}]让我们为p做同样的事情
p = [
{start_time: "11am", end_time: "3pm", priority: 1},
{start_time: "2pm", end_time: "5pm", priority: 2},
{start_time: "9am", end_time: "6pm", priority: 3}
]
q = p.each_with_object([]) do |h,a|
a << change(h).merge(priority: h[:priority])
end
#=> [{:interval=>11..15, :priority=>1},
# {:interval=>14..17, :priority=>2},
# {:interval=> 9..18, :priority=>3}] 让我们还定义一个助手来确定两个范围是否重叠:
def overlap?(r1,r2)
!(r1.first >= r2.last || r1.last <= r2.first)
end 检查一下:
overlap?( 1..10, 10..20) #=> false
overlap?( 1..11, 10..20) #=> true
overlap?(12..16, 10..20) #=> true
overlap?( 1..30, 10..20) #=> true
overlap?(20..30, 10..20) #=> false 添加优先级
现在,我们可以很容易地为b中的每个散列添加优先级。
b.each do |h|
h[:priority] = []
q.each do |g|
h[:priority] << g[:priority] if overlap?(h[:interval], g[:interval])
end
end
b #=> [{:interval=> 9..10, :priority=>[3]},
# {:interval=>10..11, :priority=>[3]},
# {:interval=>11..12, :priority=>[1, 3]},
# {:interval=>13..14, :priority=>[1, 3]},
# {:interval=>14..15, :priority=>[1, 2, 3]},
# {:interval=>15..16, :priority=>[2, 3]},
# {:interval=>16..17, :priority=>[2, 3]},
# {:interval=>17..18, :priority=>[3]}]优先级1的切片
在这种情况下,具有优先级1的散列是连续的,因此我们可以根据您的请求用数组替换它们。不过,我不知道他们是否一定会与其他数据相连。
c = b.each_with_object([]) do |h,a|
if h[:priority].include?(1)
if a.empty? || a.last.is_a?(Hash)
a << [h]
else
a.last << h
end
else
a << h
end
end
#=> [ { :interval=>9..10, :priority=>[3]},
# { :interval=>10..11, :priority=>[3]},
# [ {:interval=>11..12, :priority=>[1, 3]},
# {:interval=>13..14, :priority=>[1, 3]},
# {:interval=>14..15, :priority=>[1, 2, 3]}],
# { :interval=>15..16, :priority=>[2, 3]},
# { :interval=>16..17, :priority=>[2, 3]},
# { :interval=>17..18, :priority=>[3]}] https://stackoverflow.com/questions/29424789
复制相似问题