ruby 按哈希值分组

Posted

技术标签:

【中文标题】ruby 按哈希值分组【英文标题】:ruby group by hashes' values in hash 【发布时间】:2015-07-25 21:18:48 【问题描述】:

对不起标题,无法更好地表达自己。

我有这个:


  7758 =>  3259 => 10, 39625 => 10, 36410 => 20, 36238 => 20, 34951 => 20, 32101 => 10,
  7916 =>  3259 => 10, 39625 => 10, 36410 => 20, 36238 => 20, 34951 => 20, 32101 => 10,
  8857 =>  1000 => 10, 39625 => 10 

这些哈希的键代表记录 ID,值代表应该进入其行属性的数据。

问题是这个哈希值可能很大,因此为哈希中表示的每条记录发布数据库更新是不谨慎的。

相反,我考虑将具有相同值的散列分组,并有一个结构,我可以一次性对记录发出更新。

甚至可以通过将嵌套哈希本身转换为 json 字符串来比较哈希值,因为它是我们用于该列的数据类型。

最后我想为具有相同哈希内容的一系列变体发出update_all,我知道数据库的更新问题数量与哈希值的唯一性是 1:1 ,但是我可以选择在比较之前以某种方式对它们的键进行排序,如果我们有一些聪明的东西来比较现有值而不是将内容转换为字符串以进行比较。

现在发生的是在一个周期内对每个哈希记录进行正常更新:

UPDATE "table" SET "rates" = '"3259":10,"39625":10,"36410":20,"36238":20,"34951":20,"32101":10', WHERE "table"."variant_id" = 7758
UPDATE "table" SET "rates" = '"3259":10,"39625":10,"36410":20,"36238":20,"34951":20,"32101":10', WHERE "table"."variant_id" = 7916
UPDATE "table" SET "rates" = '"1000":10,"39625":10' WHERE "table"."variant_id" = 7916

我想将原始结构转换为允许我执行此操作的东西:

UPDATE "table" SET "rates" = '"3259":10,"39625":10,"36410":20,"36238":20,"34951":20,"32101":10', WHERE "table"."variant_id" IN(7758, 7916)
UPDATE "table" SET "rates" = '"1000":10,"39625":10' WHERE "table"."variant_id" = 7916

我试过了

hash.group_by  |h| h[1].to_json .each do |rate|

但我在rate 有这个:

["\"3259\":10,\"39625\":10,\"36410\":20,\"36238\":20,\"34951\":20,\"32101\
":10", [[7758, 3259=>10, 39625=>10, 36410=>20, 36238=>20, 34951=>20,
 32101=>10], [7916, 3259=>10, 39625=>10, 36410=>20, 36238=>20, 
34951=>20, 32101=>10], [8857, 3259=>10, 39625=>1...

【问题讨论】:

【参考方案1】:

可能是这样的:

result = hash.each_with_object() do |(id, attributes), result|
  json_string = attributes.to_json
  result[json_string] ||= []
  result[json_string] << id
end

result.each do |json_string, ids|
  # ...
end

【讨论】:

或者,您也可以只生成您已经生成的所有UPDATE 语句,然后将它们作为一大组查询发送。数据库可能需要做更多的工作,但我怀疑与您在所有这些查询上节省的往返时间相比,它会很明显

以上是关于ruby 按哈希值分组的主要内容,如果未能解决你的问题,请参考以下文章

Ruby - 按值按降序排序哈希值

ruby 合并哈希中的哈希值

哈希键的Ruby值?

ruby 将哈希值转换为排序的字符串数组,以便与另一个哈希值进行比较

使用来自另一个哈希的新值更新了 Ruby 哈希数组

ruby 哈希,其中键来自数组,值作为默认值