Ruby中的高级分组

时间:2012-03-11 18:42:25

标签: ruby-on-rails ruby

我想按照他们的日子分组事件。 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,它不应该那么难吗?

编辑:更新了示例,澄清并更正了预期输出

2 个答案:

答案 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数组进行排序也是明智的!