我想按照他们的日子分组事件。 Prefact:
Available days are 1,2,3,4,5,6,7
One event can not contain duplicates. e.g [1,1,2,3]
Setup is Ruby 1.9.2 with Rails 3.2
一个事件包含8-10个更多的属性(在示例中不必包含这些属性,但是应该考虑,这些属性在分组后仍然应该存在。)换句话说,事件对象不应仅按原样分组更改。
考虑一个包含对象的数组:
events = [
{
:name => "event1",
:days => [1,2,3,4,5]
},
{
:name => "event2",
:days => [1,4,5]
},
{
:name => "event3",
:days => [1]
},
{
:name => "event4",
:days => [2]
},
{
:name => "event5",
:days => [3]
},
{
:name => "event6",
:days => [4]
},
{
:name => "event7",
:days => [5]
},
{
:name => "event8",
:days => [1,2,3]
},
{
:name => "event9",
:days => [1,5]
},
{
:name => "event10",
:days => [1,2]
},
{
:name => "event11",
:days => [1,2,3,4,5]
}
]
要进行分组,事件必须至少有3天。这些日子应该按数字顺序排列。
示例(应分组):[1,2,3]
示例(不应分组):[1,4,5]
不适合分组的事件应放在它们包含的每一天。
示例:[1,4,5]应放在1,4和5中。
上面的事件数组所需的结果:
[
{
:heading => "1",
:events => [
{
:name => "event3",
:days => [1]
},
{
:name => "event9",
:days => [1,5]
},
{
:name => "event10",
:days => [1,2]
},
{
:name => "event2",
:days => [1,4,5]
}
]
},
{
:heading => "2",
:events => [
{
:name => "event4",
:days => [2]
},
{
:name => "event10",
:days => [1,2]
}
]
},
{
:heading => "3",
:events => [
{
:name => "event5",
:days => [3]
}
]
},
{
:heading => "4",
:events => [
{
:name => "event6",
:days => [4]
},
{
:name => "event2",
:days => [1,4,5]
}
]
},
{
:heading => "5",
:events => [
{
:name => "event7",
:days => [5]
},
{
:name => "event9",
:days => [1,5]
},
{
:name => "event2",
:days => [1,4,5]
}
]
},
{
:heading => "1-3",
:events => [
{
:name => "event8"
}
]
},
{
:heading => "1.5",
:events => [
{
:name => "event1"
},
{
:name => "event11"
}
]
}
]
这里非常先进的Ruby。也许对我来说太先进了,我所尝试的一切最终都错过了等式中的一部分。但是嘿,这是Ruby,它不应该那么难吗?
编辑:更新了示例,澄清并更正了预期输出
答案 0 :(得分:2)
require 'pp'
pp(events.inject(Hash.new { |h, k| h[k] = [] }) do |m, e|
days = e[:days]
event = { :name => e[:name] }
if days.size >= 3 && days.last - days.first + 1 == days.size
m["%d-%d" % [days.first, days.last]] << event
else
days.each { |d| m[d.to_s] << event }
end
m
end)
答案 1 :(得分:1)
我会略微修改DigitalRoss的答案。我会改变
if days.size >= 3 && days.last - days.first + 1 == days.size
到
if days.size >= 3 && (days.first..days.last).to_a == days
这将抓住[1,1,3,4] ......
在测试之前对days数组进行排序也是明智的!