2017-06-13 83 views
-1

我有红宝石二维数组,并尝试如下的数据合并:红宝石合并数组有条件

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" 

谁能帮我找出什么是最有效的方法呢?谢谢。要做到这一点

+1

请试一下,询问一下可枚举#GROUP_BY前给它一个镜头 – engineersmnky

+2

这是一个非常奇特的目标格式。 – tadman

+2

@tadman我想知道OP是否意味着'[[“a”],[“b”,“c”],[“d”],[“e”,“f”,“g”]]。 –

回答

3

一种方式是通过在每个阵列中的第二个值使用group_by到组元素,然后使用map收集并格式化相关的值:

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

查看在Ruby documentationgroup_bymap更多信息。

1

使用哈希可以是解决它的一种方法。

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 
+3

像'_array'和'_hash'这样的东西杂乱无章地表达了这个解决方案,但这是一个解决方案。不要忘记你可以分解数组中的元素:'每个都做| a,b |'避免'item [0]'和'item [1]'。 – tadman

1

这应该对你很好,尽管它确实建立了一个中介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"]