【问题标题】:Ruby merge array conditionally [closed]Ruby 有条件地合并数组 [关闭]
【发布时间】:2017-06-13 18:12:50
【问题描述】:

我在ruby中有一个二维数组,尝试合并数据如下:

a = [["a","1"],["b","2"],["c","2"],["d","3"],["e","4"],["f","4"],["g","4"]]

我想把它变成

 [["a"],["b c"],["d"],["e f g"]] //merge each letter together if they have the same "key"

谁能帮我弄清楚最有效的方法是什么?谢谢。

【问题讨论】:

  • 请在询问之前尝试一下 Enumerable#group_by 并试一试
  • 这是一种非常奇特的目标格式。
  • @tadman 我想知道 OP 是否意味着[["a"], ["b", "c"], ["d"], ["e", "f", "g"]]
  • “键”是否总是按顺序排列,如您的示例所示?
  • @JordanRunning 你认为chunk_while 是一种选择吗?

标签: arrays ruby merge


【解决方案1】:

一种方法是使用group_by按每个数组中的第二个值对元素进行分组,然后使用map收集和格式化相关值:

a.group_by(&:last).map { |k,v| [v.map(&:first).join(' ')] }
#=> => [["a"], ["b c"], ["d"], ["e f g"]]

有关详细信息,请参阅 Ruby documentation 中的 group_bymap

【讨论】:

    【解决方案2】:

    使用 Hash 可能是解决问题的一种方法。

    initial_array = [["a","1"],["b","2"],["c","2"],["d","3"],["e","4"],["f","4"],["g","4"]]
    constructed_hash = {}
    initial_array.each do |item|
      constructed_hash[item[1]] = constructed_hash[item[1]].to_a << item[0]
    end
    final_array = constructed_hash.values
    

    【讨论】:

    • _array_hash 之类的东西以毫无意义的冗长使这个解决方案变得混乱,但这是一个解决方案。不要忘记您可以拆分数组中的元素:each do |a, b| 避免使用 item[0]item[1]
    【解决方案3】:

    这对你也应该很有效,尽管它确实构建了一个中介 Hash 它只需要一次迭代。

    a.each_with_object(Hash.new {|h,k| h[k] =''}) do |(v, k),obj| 
      (obj[k] << " #{v}").strip! 
    end.values
    #=> ["a", "b c", "d", "e f g"]
    

    或使用Array(假设“键”是数字和位置,就像它们在问题中一样,否则恢复为选项 1)

    a.each_with_object([]) do |(v,k), obj|
      ((obj[k.to_i - 1] ||= "") << " #{v}").strip!
    end
    #=> ["a", "b c", "d", "e f g"]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 2018-11-12
      • 2012-09-07
      相关资源
      最近更新 更多