我有一个SQL查询的数组:
Array = [
["a","ab",1,548], ["a","ab",2,215],
["b","ba",1,999], ["c","ca",1,784]
]
不可能在子阵列 的“第三行”中使用两个相同的值,其中2个第一个相同的值/阅读帖子的每一行 。
["a","ab",**1**,548], ["a","ab",**2**,215]
可能,但
["a","ab",**1**,548], ["a","ab",**1**,895]
不可能
它来自SQL“group by”查询3个第一个值。
预期结果:
Array = [ ["a","ab", {1=>548, 2=>215} ],
["b","ba", {1=>999} ], ["c","ca", {1=>784}] ]
我尝试了group_by
map
的某些组合,但我没有成功。
Array.rows.group_by{|v| v}.map do |k|
k[0] << {k[0][2]=>k[0][3]}
end
我明白了:
Array = [ ["a","ab", {1=>548} ], ["a","ab", {2=>215} ],
["b","ba", {1=>999} ], ["c","ca", {1=>784}] ]
"a","ab"
未合并。
编辑:我忘了,2个第一个值可以是零。 [nil,nil,1,875]
答案 0 :(得分:4)
a = [["a","ab",1,548], ["a","ab",2,215],["b","ba",1,999], ["c","ca",1,784]]
a.group_by { |e| e.shift(2) }.map { |k, v| k << Hash[v] }
# => [["a", "ab", {1=>548, 2=>215}], ["b", "ba", {1=>999}], ["c", "ca", {1=>784}]]
group_by
按前两个键创建组,将最后两个键保留为值:
# => {["a", "ab"]=>[[1, 548], [2, 215]], ["b", "ba"]=>[[1, 999]], ["c", "ca"]=>[[1, 784]]}
这已经非常类似于您的需求,您只需要将Hash
切换为Array
,将Array
切换为Hash
- 这就是{ {1}}确实。
重要说明:此解决方案 destructive ,这意味着在运行此代码时map
本身会发生更改(a
更改实际数组数组。)
答案 1 :(得分:1)
您可以使用以下方法,将值“键”(即第一个和第二个元素)分组,并另外创建第3个元素到第4个元素的哈希值。这似乎就是你想要的。
array = [
["a","ab",1,548], ["a","ab",2,215],
["b","ba",1,999], ["c","ca",1,784]
]
result = array.inject({}) { |h, sub|
key, idx, val = sub[0..1], sub[2], sub[3]
h.tap { (h[key] ||= {})[idx] = val }
}.map { |k,v| k << v }
# => [["a", "ab", {1=>548, 2=>215}], ["b", "ba", {1=>999}], ["c", "ca", {1=>784}]]