Ruby 执行分组方式并使用聚合值创建哈希

Ruby 执行分组方式并使用聚合值创建哈希,ruby,Ruby,我有一个SQL查询结果数组: Array = [ ["a","ab",1,548], ["a","ab",2,215], ["b","ba",1,999], ["c","ca",1,784] ] 不可能在子数组的“第三行”中有两倍相同的值,第一行有两个相同的值/读取post的每一行 [“a”,“ab”,“1**,548”,“a”,“ab”,“2**,215]可能,但 [“a”,“ab”,“**1**,548],“a”,“ab”,“**1**,89

我有一个SQL查询结果数组:

Array = [
        ["a","ab",1,548], ["a","ab",2,215],
        ["b","ba",1,999], ["c","ca",1,784]
        ]
不可能在子数组的“第三行”中有两倍相同的值,第一行有两个相同的值/读取post的每一行

[“a”,“ab”,“1**,548”,“a”,“ab”,“2**,215]
可能,但

[“a”,“ab”,“**1**,548],“a”,“ab”,“**1**,895]
不可能

它来自对前3个值的SQL“GROUPBY”查询

预期结果:

Array = [ ["a","ab", {1=>548, 2=>215} ], 
["b","ba", {1=>999} ], ["c","ca", {1=>784}] ]
我尝试了一些
groupby
map
组合,但没有成功

Array.rows.group_by{|v| v}.map do |k|
  k[0] << {k[0][2]=>k[0][3]}
end
“a”、“ab”
不合并


编辑:我忘了,前两个值可以是零
[nil,nil,1875]

您可以使用以下方法,对其“键”(即第一个和第二个元素)上的值进行分组,并另外创建映射到第四个元素的第三个元素的散列。看来这就是你想要的

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}]]
数组=[
[“a”,“ab”,1548],“a”,“ab”,2215],
[“b”,“ba”,1999年],“c”,“ca”,1784年]
]
result=array.injection({}){h,sub|
键,idx,val=sub[0..1],sub[2],sub[3]
h、 轻触{(h[键]| |={})[idx]=val}
}.map{k,v|k[[“a”,“ab”,“1=>548,2=>215}],“b”,“ba”,“{1=>999}],“c”,“ca”,“{1=>784}]]

您可以使用以下方法,将其“键”(即第一个和第二个元素)上的值分组,并另外创建第三个元素映射到第四个元素的散列。这似乎是您想要的

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}]]
数组=[
[“a”,“ab”,1548],“a”,“ab”,2215],
[“b”,“ba”,1999年],“c”,“ca”,1784年]
]
result=array.injection({}){h,sub|
键,idx,val=sub[0..1],sub[2],sub[3]
h、 轻触{(h[键]| |={})[idx]=val}
}.map{k,v|k[[“a”,“ab”,“1=>548,2=>215}],“b”,“ba”,“{1=>999}],“c”,“ca”,“{1=>784}]]
这已经非常类似于您所需要的,您只需要将
散列
切换到
数组
,将
数组
切换到
散列
——这就是
映射所做的

重要提示:此解决方案具有破坏性,这意味着运行此代码时,
a
本身会发生更改(
shift
更改数组中的实际数组。)

这已经非常类似于您所需要的,您只需要将
散列
切换到
数组
,将
数组
切换到
散列
——这就是
映射所做的


重要提示:此解决方案具有破坏性,这意味着运行此代码时,
a
本身会发生更改(
shift
更改数组中的实际数组。)

你的
数组
有三个元素,它们的第三个值是
1
,然后你写了这是不可能的。为什么?你是什么意思?哪里?“a”,“ab”不同于“c”,“ca”不同于“b”,“ba”“阅读文章的每一行[sic]”--关于编辑2,您之前在帖子中说过这些结果是不可能的。
[nil,nil,1,X]
根据您的OP将在一个组中。您的
数组
有三个元素,它们的第三个值是
1
,然后您编写了这是不可能的。为什么会这样?您的意思是什么?a和ab在哪里不同“c”、“ca”不同于“b”、“ba”“阅读文章的每一行[sic]”——关于编辑2,你之前在文章中说过,这些结果是不可能的
[nil,nil,1,X]
根据你的操作将在一个组中。巧妙地使用
shift(2)
在那里。很高兴您注意到它具有破坏性,因为这可能会让使用它的人感到困惑。谢谢,我不知道选择什么解决方案。但我根本不想更改“a”数组。(我在代码中进一步使用它,但我可以创建“a”的克隆)仅仅因为我喜欢它的外观,你就可以通过
a.groupu by{e | e.take(2)}.map{k,v | k巧妙地使用
shift(2)使它成为非破坏性的,尽管不那么干净
在那里。很高兴您注意到它具有破坏性,因为这可能会让使用它的人感到困惑。谢谢,我不知道选择什么解决方案。但我根本不想更改“a”数组。(我在代码中进一步使用它,但我可以创建“a”的克隆)仅仅因为我喜欢它的外观,你就可以用
a.groupu by{e | e.take(2)}.map{k,v | k使它成为非破坏性的,尽管不那么干净
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}]] 
# => {["a", "ab"]=>[[1, 548], [2, 215]], ["b", "ba"]=>[[1, 999]], ["c", "ca"]=>[[1, 784]]}