【问题标题】:How do I compare two hashes containing ~25000 hashes?如何比较包含 ~25000 个哈希的两个哈希?
【发布时间】:2014-10-07 01:54:19
【问题描述】:

我有两个包含多个哈希的哈希(产品信息)。

我想做的是比较两个哈希值,看看添加、删除、更新了哪些产品(例如价格、描述、图片)。

old_hash.size
# => 24595

new_hash.size
# => 26153

这两个哈希的结构如下所示:

{"wi230075"=>
  {"itemId"=>"wi230075",
   "description"=>"AH Verse frietaardappelen",
   "salesUnitSize"=>"2,5 kg",
   "images"=>[...]
   "fromPrice"=>2.19,
   "basePrice"=>{"price"=>2.19, "unitPriceDescription"=>"0.96/KG"},
   "score"=>0,
   "frozen"=>false,
   "isPBO"=>false,
   "outOfStock"=>false,
   "quantity"=>0,
   "extendedAttributes"=>[],
   "sourceId"=>{"source"=>"wi", "id"=>230075, "asString"=>"wi230075"},
   "hqIdSource"=>"AH_HQ",
   "hqId"=>822729,
   "productId"=>230075,
   "links"=>[],
   "category"=>"/Aardappel, groente, fruit/Aardappelen/Hele aardappel/",
   "brand"=>"AH"},
  {...}
}

我尝试使用HashDiff gem 比较两个哈希值。这是我得到的:

diff = HashDiff.diff(old_hash, new_hash)
diff.size
# => 64378

好像出了点问题,不能有 64378 的变化。

比较两个哈希值的更好方法是什么?

编辑:

我只想知道产品是否被添加、删除或编辑。如果是这样,一个简单的true 就足够了。

【问题讨论】:

  • 那个 gem 不会知道要比较哪些内部哈希值,这就是为什么在你得到的输出中一切看起来都不同的原因。
  • 为什么你认为不能有64378 的区别?一个新的顶级元素将产生N 补丁,其中N 是子键的数量。仔细查看文档。
  • 这可能应该使用数据库来完成。他们真的很擅长解决这类问题。
  • @mudasobwa 因为大约 1% 的产品略有变化,例如价格或描述。
  • @narzero 1500 条全新记录产生 N×1500 差异。这很容易给出 64K。如果您只需要检查现有产品的差异,则应在与old_hash 相交的new_hash 上运行HashDiff

标签: ruby hash compare


【解决方案1】:

这将返回所有已更改(即创建、删除或更新)的键:

(old_hash.keys | new_hash.keys).select { |k| old_hash[k] != new_hash[k] }

要具体,您可以执行以下操作:

keys = (old_hash.keys | new_hash.keys)
new_keys = keys.select { |k| old_hash[k].nil? }
deleted_keys = keys.select { |k| new_hash[k].nil? }
modified_keys = keys.select { |k| old_hash[k] != new_hash[k] }
unchanged_keys = keys - (new_keys | deleted_keys | modified_keys)

这假设您对具有 nil 值的键不感兴趣。如果是,那么您显然应该替换 .nil?用别的东西打电话。

【讨论】:

    【解决方案2】:

    我没有测试代码,但我认为它看起来像这样

    获取添加的记录:

    added_keys = new_hash.keys - old_hash.keys
    added_records = new_hash.select{|k,v| added_keys.include? k}
    

    要获取删除的记录:

    removed_keys = old_hash.keys - new_hash.keys
    removed_records = old_hash.select{|k,v| removed_keys.include? k}
    

    要获取更改的记录:

    changed_records = new_hash.select do |k,v|
      old_hash.has_key?(k) && (old_hash[k]["description"] != new_hash[k]["description"] || old_hash[k]["images"] != new_hash[k]["images"] || old_hash[k]["basePrice"] != new_hash[k]["basePrice"] )
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多