2015-10-14 86 views
1

我想要在ruby中减去两个json文件,并将区别写入第三个文件。例如我怎样才能在ruby中下载两个json文件

file1.json

{ 
    "id" : "file1", 
    "att1" : { 
    "attA" : { 
     "free_mem" : "1234", 
     "buff_mem" : "5678" 
    }, 
    "attB" : { 
     "name" : "Joe", 
     "location" : "Lab" 
    } 
    } 
} 

file2.json

{ 
    "att1" : { 
    "attA" : { 
     "free_mem" : "3457", 
     "buff_mem" : "6789" 
    } 
    } 
} 

所得flle3.json文件

file3.json

{ 
    "id" : "file1", 
    "att1" : { 
    "attB" : { 
     "name" : "Joe", 
     "location" : "Lab" 
    } 
    } 
} 

这只是一个例子文件。真正的file1.json可能有多个嵌套在att1中的属性,它们本身可以是嵌套属性。同样,我所拥有的file2.json文件可能有多个嵌套在att1中的属性,它们本身可以是嵌套属性。但是,每个文件中的嵌套结构是相似的。例如,IOW,attA将嵌套在两个文件的att1中。谢谢!

编辑回答佩德罗的问题:“你尝试过什么到目前为止”

我试过这个Ruby代码,但我没有得到我想要的结果。

require 'rubygems' 
require 'json' 

unless ARGV.count > 1 
    puts "Usage: json_diff.rb json_file_1.json json_file_2.json" 
    puts "AND json_diff.rb json_file_2.json json_file_1.json" 
    exit 
end 


json_a = JSON.parse(File.read(ARGV[0])) 
json_b = JSON.parse(File.read(ARGV[1])) 

array_diff = ["#{json_a}"] - ["#{json_b}"] 

puts array_diff.to_s 

Cary的代码有效!这是完整的实现。

require 'rubygems' 
require 'json' 

unless ARGV.count > 1 
    puts "Usage: json_diff.rb json_file_1.json json_file_2.json" 
    puts "AND json_diff.rb json_file_2.json json_file_1.json" 
    exit 
end 

def subtract(h1, h2) 
    h1_deep_copy = Marshal.load(Marshal.dump(h1)) 
    recurse(h1_deep_copy, h2) 
    h1_deep_copy 
end 

def recurse(h1, h2) 
    result = h1.keys.map do |k| 
    remove = 
    if !h2.key?(k) 
     remove = false 
    elsif !h1[k].is_a?(Hash) 
     remove = true 
    elsif !h2[k].is_a?(Hash) 
     remove = false 
    else 
     recurse(h1[k], h2[k]) 
    end 
    h1.delete(k) if remove 
    remove 
    end 
    result.uniq == [true] 
end 

h1 = JSON.parse(File.read(ARGV[0])) 
h2 = JSON.parse(File.read(ARGV[1])) 
h1 = subtract(h1, h2) 
puts h1.to_s 
+0

可能重复question/11958374 /从另一个哈希中的相应值中减去哈希数值 – ptierno

+1

如果您具有相同的密钥但不相同的值,该怎么办?考虑到这一点:'{“key1”:“value is string”}'and'{“key1”:{“value”:“is string”}}' –

+0

Jean Bob,没关系,只要key1不是我想要删除的属性。 –

回答

0

比方说,你看这些文件并将它们转换成哈希h1h2。我们可以执行以下操作来获得所需的散列。

代码

def subtract(h1, h2) 
    h1_deep_copy = Marshal.load(Marshal.dump(h1)) 
    recurse(h1_deep_copy, h2) 
    h1_deep_copy 
end 

def recurse(h1, h2) 
    result = h1.keys.map do |k| 
    remove = 
    if !h2.key?(k) 
     false 
    elsif !h1[k].is_a?(Hash) 
     true 
    elsif !h2[k].is_a?(Hash) 
     false 
    else 
     recurse(h1[k], h2[k]) 
    end 
    h1.delete(k) if remove 
    remove 
    end 
    result.uniq == [true] 
end 

正如所指出的,这两种方法Marshal用于获得的h1深层副本。

转换后各JSON串的假设,以哈希我们得到:

h1 = { "id": "file1", 
     "att1": { 
     "attA": { 
      "free_mem": "1234", 
      "buff_mem": "5678" 
     }, 
     "attB": { 
      "name": "Joe", 
      "location": "Lab" 
     } 
     } 
    } 

h2 = { "att1": { 
     "attA": { 
      "free_mem": "3457", 
      "buff_mem": "6789" 
     } 
     } 
    } 

然后:http://stackoverflow.com/的

subtract(h1, h2) 
    #=> {:id=>"file1", :att1=>{:attB=>{:name=>"Joe", :location=>"Lab"}}} 
+0

谢谢,我会试试这个。 –

+0

这不适合我。我得到{“id”=>“file1”,“att1”=> {“attA”=> {“free_mem”=>“1234”,“buff_mem”=>“5678”},“attB”=>名称“=>”乔“,”位置“=>”实验室“}}}。我会编辑我的帖子以包含所有代码,包括Cary的 –

+0

我不明白。你说它在你编辑的问题中起作用了。 –