【问题标题】:Group by week in the first column of an array ruby在数组 ruby​​ 的第一列中按周分组
【发布时间】:2017-07-18 14:04:24
【问题描述】:

我有下一个二维数组,其中第一个组件属于 ActiveSupport::TimeWithZone,第二个组件是一个字符串

[[Sun, 16 Jul 2017 14:41:56 -03 -03:00, "open"],
 [Sun, 16 Jul 2017 14:41:56 -03 -03:00, "closed"],
 [Sun, 16 Jul 2017 14:41:56 -03 -03:00, "closed"],
 [Mon, 10 Jul 2017 00:00:00 -03 -03:00, "open"],
 [Sun, 16 Jul 2017 14:45:31 -03 -03:00, "closed"],
 [Sun, 16 Jul 2017 14:44:41 -03 -03:00, "open"],
 [Sun, 16 Jul 2017 14:44:39 -03 -03:00, "closed"],
 [Sun, 16 Jul 2017 14:44:13 -03 -03:00, "open"],
 [Mon, 10 Jul 2017 00:00:00 -03 -03:00, "closed"],
 [Fri, 14 Jul 2017 00:00:00 -03 -03:00, "open"],
 [Mon, 17 Jul 2017 00:00:00 -03 -03:00, "open"]]

我需要以有效的方式将该数组转换为

{["09-Jul", "open"]=>2, ["16-Jul", "open"]=>1, ["09-Jul", "closed"]=>0, ["16-Jul", "closed"]=>1}

也就是说,我需要将第一个组件转换为 %b-%d 格式。另外,我需要按周分组和“状态”。最后我需要对这些分组值进行计数,并以哈希格式呈现数据作为第二个示例

【问题讨论】:

  • 你想出的低效方法是什么?

标签: ruby-on-rails ruby


【解决方案1】:
input.group_by { |d, v| [d.strftime('%b-%d'), v] }
     .map { |k, v| [k, v.count] }.to_h

此外,对于 Ruby 2.4+,它可以简化为:

input.group_by { |d, v| [d.strftime('%b-%d'), v] }
     .transform_values(&:count)

【讨论】:

  • Rails 4.2+ 中的mapto_h 可以替换为.transform_values(&:count)
  • @MarkThomas 我是一名毕业的 Rails 仇恨者。
  • ...或Ruby 2.4+ :-)
【解决方案2】:

您可以使用Hash::new 的形式创建所需的散列,它的参数等于散列的默认值,这里我们希望它为零。这意味着如果散列h,定义为h = Hash.new(0),没有键k,则h[k] 返回默认值(此处为0),而不修改散列h

input.each_with_object(Hash.new(0)) { |(d,v),h| h[[d.strftime('%b-%d'), v]] += 1 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多