我有一系列哈希
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
然而,它并不起作用,而且在我不需要的时候,我可能会把事情弄平,而且对于大型数据集来说它可能会很慢。
如果你能提供任何令人敬畏的帮助。
答案 0 :(得分:1)
试试这个:
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小时格式。
答案 1 :(得分:1)
这只是部分答案。我将建议您如何将优先级添加到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]}]