将键数组与预定义数组进行比较 - Ruby

Compare array of keys against predefined array - Ruby

我想将我在所有结果的 JSON 响应中返回的键与预定义的键数组进行比较。

所以我有这组钥匙

def key_array
 ["key1", "key2", "key3"] 
end

我对 api 呼叫的响应是 return 以这种格式(哈希数组)输出的 @response

{"0"=>
  {"key1"=>"value1",
   "key2"=>"value2",
   "key3"=>"value3"},
 "1"=>
   {"key1"=>"value1",
    "key2"=>"value2",
    "key3"=>"value3"},
 "2"=>
   {"key1"=>"value1",
    "key2"=>"value2",
    "key3"=>"value3"},
 "Status"=>"100"}
}

当我做 @response.keys 我得到

["0", "1", "2"]

我可以使用 @response["0"].keys 通过其索引单独访问每组键,例如将 return

  ["key1", "key2", "key3"]

我想用 rspec 匹配器做的是检查 api 调用的每个 returned 结果是否在 key_array

目前

expect(@response.keys).to match_array(key_array)

正在将索引数组与我存储的 key_array 进行匹配。如何从每个索引中访问键?

required_keys = %w{key1 key2 key3}
@response.each do |key, hash|
  next if (key == "Status")
  expect(hash).to include(*required_keys)
end

您可以添加一条可选消息以查看发生故障的索引:

@response.each do |key, hash|
  next if (key == "Status")
  expect(hash).to include(*required_keys), "Failed at #{key}"
end

next 检查可以变成正则表达式检查,以防您有其他想要忽略的非数字键,例如

next if /\D/.match(key) # the \D matches non-digits
@response.each_value do |value|
  expect(value.keys).to match_array(key_array)
end

这对你有用。

如果你只想调用一次expect方法,你可以这样做

expect( @response.values.map{|h| h.keys.sort}.uniq ).to eq([%w(key1 key2 key3)])

然而这是相当丑陋的方法

先收残缺:

incompletes = @response.reduce([]) { |memo, kv| 
  (key_array - kv.last.keys).empty? ? memo : memo << kv.first 
}

然后做检查:

expect(incompletes).to match_array([])

是否只需要检查:

incompletes = @response.reject { |*kv| (key_array - kv.last.keys).empty? }
expect(incompletes).to match_array([]) 

前一种方法可以轻松收集有关错误条目的任何所需信息,因为您可以自由地将任何有价值的内容放入结果数组中。希望对你有帮助。

UPD 状态:

incompletes = @response.reject { |k,v| 
# ⇓⇓ is k integer? ⇓⇓  or  ⇓⇓ are valid keys all presented? ⇓⇓
   k.to_i.to_s != k    ||      (key_array - v.keys).empty? 
}
expect(incompletes).to match_array([])