2014-10-06 113 views
0

我有两个哈希包含多个哈希(产品信息)。如何比较两个包含〜25000个哈希的哈希?

我想要做的是比较两个哈希值,看看有什么产品被添加,删除,更新(例如价格,描述,图片)。

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就足够了。

+1

那宝石不会知道要比较哪些内部哈希值,这就是为什么一切看起来都不一样的原因。 – squiguy 2014-10-06 17:07:35

+1

你为什么认为不能有'64378'差异?一个新的顶级元素将产生'N'个补丁,其中'N'是一些子密钥。仔细查看文档。 – mudasobwa 2014-10-06 17:10:32

+3

这可能应该使用数据库来完成。他们非常擅长这类问题。 – 2014-10-06 17:12:17

回答

2

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

(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?与别的东西打电话。

1

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

为了让添加的记录:

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