代码之家  ›  专栏  ›  技术社区  ›  The Whiz of Oz

要哈希的Ruby数组,日期为键

  •  -1
  • The Whiz of Oz  · 技术社区  · 8 年前

    我有一个这样的数组:

    [
      ["20180630", "14:49", "google", "iOS", "Safari", "1"], 
      ["20180630", "12:22", "google", "Android", "Chrome", "2"],
      ["20180629", "17:20", "google", "iOS", "Safari", "1"], 
      ["20180629", "16:30", "(direct)", "iOS", "Safari", "1"], 
      ["20180629", "09:29", "(direct)", "Android", "Chrome", "2"]
    ]
    

    我想要的输出是一个散列,其中日期作为键:

    {
      "20180630": [["14:49", "google", "iOS", "Safari", "1"],["12:22", "google", "Android", "Chrome", "2"]],
      "20180629": [[...],[...],[...]]
    }
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   matthewd    8 年前

    Enumerable#group_by 将为您提供数组转换的散列,然后只需从结果值中删除多余的列:

    hash = input_array.group_by(&:first)
    hash.each { |_, list| list.each(&:shift) }
    hash
    

    (请注意,这会修改原始数组;如果出现问题,您需要调整到具有更多复制和更少突变的版本)

        2
  •  2
  •   Cary Swoveland    8 年前

    以下是构建所需哈希的两种方法。两者都不会改变给定的数组( arr )。

    arr = [
      ["20180630", "14:49", "google", "iOS", "Safari", "1"], 
      ["20180630", "12:22", "google", "Android", "Chrome", "2"],
      ["20180629", "17:20", "google", "iOS", "Safari", "1"], 
      ["20180629", "16:30", "(direct)", "iOS", "Safari", "1"], 
      ["20180629", "09:29", "(direct)", "Android", "Chrome", "2"]
    ]
    
    arr.each_with_object({}) { |a,h| (h[a.first] ||= []) << a.drop(1) }
      #=> {"20180630"=>[["14:49", "google", "iOS", "Safari", "1"],
      #                 ["12:22", "google", "Android", "Chrome", "2"]],
      #   "20180629"=>[["17:20", "google", "iOS", "Safari", "1"],
      #                ["16:30", "(direct)", "iOS", "Safari", "1"],
      #                ["09:29", "(direct)", "Android", "Chrome", "2"]]}
    

    变量如下。

    arr.each_with_object(Hash.new { |h,k| h[k] = [] }) { |a,h| h[a.first] << a.drop(1) }
    

    或者,可以使用 Hash#update (又名 merge! )它使用一个块来确定合并的两个哈希中存在的键的值。

    arr.each_with_object({}) { |a,h| h.update(a.first=>[a.drop(1)]) { |_,o,n| o+n } }
    
    推荐文章