代码之家  ›  专栏  ›  技术社区  ›  Russ Bradberry

如何将唯一值从多级数组映射到value=>数组的散列?

  •  2
  • Russ Bradberry  · 技术社区  · 14 年前

    我有一个数组,看起来像这样:

    [[100, "one"],
     [101, "one"],
     [102, "one"],
     [103, "two"],
     [104, "three"],
     [105, "three"]]
    

    我想做的是创建一个如下所示的哈希数组

    [{"one" => [100,101,102]},
     {"two" => [103]},
     {"three" => [104,105]}]
    

    数字部分将始终是唯一的,字符串部分将有重复项。每次我想到这个我都会得到一些很长的函数,我想知道“rails方法”,我确信我遗漏了一些模糊的函数。

    8 回复  |  直到 14 年前
        1
  •  5
  •   Joseph Weissman    14 年前

    不是Rails助手,但是一个常见的Ruby习惯用法可以帮助您实现这一点。一点

    arr.inject({}) { |h,(v,k)| h[k] ||= []; h[k] << v; h }
    

        2
  •  2
  •   Sławosz    14 年前
    array = [[100, "one"], [101, "one"], [102, "one"], [103, "two"], [104, "three"], [105, "three"]]
    h = Hash.new { |h,k| h[k] = []}
    array.each { |a| h[a[1]] << a[0] }
    
        3
  •  1
  •   mb14    14 年前

    如果你只需要一组东西,那么你可以使用Rails group_by 功能:

    [[100, "one"],
     [101, "one"],
     [102, "one"], 
     [103, "two"],
     [104, "three"],
     [105, "three"]].group_by { |a| a[1] }
    
     => #<OrderedHash {"three"=>[[104, "three"], [105, "three"]],
                       "two"=>[[103, "two"]], 
                       "one"=>[[100, "one"], [101, "one"], [102, "one"]]}
    

    离你需要的不远。所以,如果你能按原样使用,我想没关系,但如果你需要详细说明你所说的格式。我认为自己做比用这个和转换更容易。

        4
  •  0
  •   shingara    14 年前

    没有真正的功能可以做到这一点。你需要使用inject并创建你自己的散列。

        5
  •  0
  •   rfunduk    14 年前

    a = [...your data...]
    r = a.inject( {} ) do |h, el|
      h[el.last] ||= []
      h[el.last] << el.first
      h
    end
    

    结果如下: {'one' => [101, 102], ... } 这比你对一键哈希数组的请求要好,IMO。

        6
  •  0
  •   Chubas    14 年前

    这里有一个实现

    your_array.inject(Hash.new{|h,k| h[k] = []}) do |result, (a, b)|
      result[b] << a
      result
    end
    
        7
  •  0
  •   Jörg W Mittag    14 年前

    特定格式,即单元素散列数组而不是bog标准散列?因为那样的话

    arr.group_by(&:last)
    
        8
  •  0
  •   einarmagnus    14 年前

    a = [[100, "one"],
         [101, "one"],
         [102, "one"], 
         [103, "two"],
         [104, "three"],
         [105, "three"]]
    
    b = a.group_by(&:pop)
    #=> {"three"=>[[104], [105]], "two"=>[[103]], "one"=>[[100], [101], [102]]}
    

    这可能就是你想要的。

    请注意 a 被这个毁了

    a
    #=> [[100], [101], [102], [103], [104], [105]]
    

    b = a.map(&:dup).group_by &:pop
    

    相反。

    如果你真的想要你写的格式,那么你可以添加另一个地图:

    b.map{|h,k| [h => k]}
    #=> [{"one" => [100,101,102]}, {"two" => [103]}, {"three" => [104,105]}]
    

    综上所述:

    [[100, "one"],
     [101, "one"],
     [102, "one"], 
     [103, "two"],
     [104, "three"],
     [105, "three"]].group_by(&:pop).map{ |h,k| [h => k] }