将 CSV 文件中的每一行与匹配元素上的 JSON 哈希进行比较以仅获得唯一匹配项

Comparing each line in CSV file to JSON hash on matching element to get unique matches only

我在发布之前搜索了 SO,但可能我不知道正确的搜索词。

我成功地将 CSV 文件读取到一个新数组中,并尝试将数组中的第八个元素与我的程序的 JSON 响应进行比较。来自我的程序 (data["ip"]) 的 JSON 响应只是一个与 row[8].

中的内容相匹配的 IP 地址

一切都适用于匹配,但是在每次循环迭代中都会发现三个不匹配。 JSON 中唯一不存在的 IP 地址是 100.100.100.300,所有其他 IP 地址都会匹配。

我的代码:

require 'csv'
require 'json'
require 'date'

CSV.foreach("list.csv", :headers => true) do |row|
  @response["response"]["results"].each do |data| 
     if row[8].eql?(data["ip"])
      puts "Match: " + row[8] + " = " + data["ID"]
    else
      puts "No Match Found for " + row[8]
    end
  end
end

这是我想要的结果:

Match: 100.100.100.200 = 26826
Match: 100.100.100.100 = 26827
Match: 100.100.100.400 = 26827
No Match Found for 100.100.100.300

这是我得到的结果:

No Match Found for 100.100.100.200
Match: 100.100.100.200 = 26826
No Match Found for 100.100.100.200
No Match Found for 100.100.100.200
No Match Found for 100.100.100.300
No Match Found for 100.100.100.300
No Match Found for 100.100.100.300
No Match Found for 100.100.100.300
Match: 100.100.100.100 = 26827
No Match Found for 100.100.100.100
No Match Found for 100.100.100.100
No Match Found for 100.100.100.100
No Match Found for 100.100.100.400
No Match Found for 100.100.100.400
No Match Found for 100.100.100.400
Match: 100.100.100.400 = 26827

'list.csv' 看起来像这样:

Applicability,Person,Tier,Type,AType,Name,Code,Sub,IP Address,Location,Presence,Env,Main,Main2,Status,Contact,Group,FQDN,Outside,OutsideIdent,Category,Comments
Yes,Unit,Accepted,Level,Hardware,NameA,C1234565,Yes,100.100.100.200,"Nowhere",No,VP,Running,SomeKind,Active,"","",FullName,"","",Tool,""
Yes,Unit,Accepted,Level,Hardware,NameB,C1234566,Yes,100.100.100.300,"Nowhere",No,VP,Running,SomeKind,Inactive,"","",FullName,"","",Tool,""
Yes,"","",Something,Hardware,NameC,C1234567,Yes,100.100.100.100,"Nowhere",,"",,,"","Name, Contact","",FullNameFull,"","",Tool,""
Yes,"","",Something,Hardware,NameD,C1234568,No,100.100.100.400,"Nowhere",,"",,,"","Name, Contact","",FullNameFull,"","",Tool,""

您可能不需要两个循环。你可以这样做: (未测试,因为 JSON 结构未在问题中共享)

results = @response["response"]["results"]

CSV.foreach("list.csv", :headers => true) do |row|
  matching_entry  = results.find { |data| row["IP Address"] == data["ip"]}
  if matching_entry
    puts "Match: " + row["IP Address"] + " = " + matching_entry["ID"]
  else
    puts "No Match Found for " + row["IP Address"]]
  end
end

另一种方法是创建一个以 IP 地址为键的散列。好处是它只需迭代一次即可创建查找。

ip_table = Hash[@response['response']['results'].map {|x| [x['ip'], x['ID']]}]

CSV.foreach("list.csv", :headers => true) do |row| 
  if ip_table[row[8]]
    puts "Match: " + row[8] + " = " + ip_table[row[8]]
  else
    puts "No Match Found for " + row[8]
  end
end