我在尝试遍历两个哈希数组时遇到问题。我的哈希值如下所示:
h1= [
{"name"=>"postgresql", "version"=>29},
{"name"=>"java", "version"=>8},
{"name"=>"python", "version"=>3}
]
h2= [
{"name"=>"postgresql", "release"=>"postgresql-release", "url"=>"https://github.com/repo/postgresql-release"},
{"name"=>"java", "release"=>"java-release", "url"=>"https://github.com/repo/java-release"}
]
combined = []
在我检查h1和h2中“name”字段的哈希值后,我需要将这两个哈希组合在一个名为组合
的数组中,以便:
h1[“name”]==h2[“name“]
---组合
数组应如下所示:
combined = [
{"name"=>"postgresql", "version"=>29, "release"=>"postgresql-release", "url"=>"https://github.com/repo/postgresql-release"},
{"name"=>"java", "version"=>8, "release"=>"java-release", "url"=>"https://github.com/repo/java-release"},
{"name"=> "python", "version"=>3, "release"=> nil, "url"=> nil}
]
我已经尝试了很多,并且总是有更多的迭代和/或在不同名称的情况下无法打印任何内容。
我的代码看起来像:
h1= [{"name"=>"postgresql", "version"=>29}, {"name"=>"java", "version"=>8}, {"name"=>"python", "version"=>3}]
h2= [{"name"=>"postgresql", "release"=>"postgresql-release", "url"=>"https://github.com/repo/postgresql-release"}, {"name"=>"java", "release"=>"java-release", "url"=>"https://github.com/repo/java-release"}]
combined = []
h1.each do |h1Key, h1Value|
h2.each do |h2Key, h2Value|
if h1["name"] == h2["name"]
combined << {"name"=> h1["name"], "version"=> h1["version"], "release"=> h2["release"], "url"=> h2["url"]}
else
combined << {"name"=> h1["name"], "version"=> h1["version"], "release"=> nil, "url"=> nil}
end
end
end
puts combined.to_s
我也无法正确比较h1和h2的值。
非常感谢您的帮助,因为我对Ruby还很陌生,不幸的是,我的逻辑无法帮助我。
提前感谢!^^
可能有很多方法可以做到这一点,但由于你的内部哈希本质上有一个键,所以首先想到的是将你的哈希数组转换为哈希数组,然后简单地使用Hash#deep_merge,这正是这种方法。
hash1 = h1.index_by { |inner_hash| inner_hash['name'] }
hash2 = h2.index_by { |inner_hash| inner_hash['name'] }
combined_hash = hash1.deep_merge(hash2)
combined = combined_hash.values
这给出了除python nil URL之外的预期输出。如果无法在数据中修复该问题,要复制该结果,请尝试如下操作:
# ... as before
defaults = {'url' => nil, 'version' => nil}
combined_hash = combined_hash.transform_values { |v| defaults.merge(v) }
combined = combined_hash.values
如果您需要默认值是数据中可能更改的确切键:
keys = (hash1.keys + hash2.keys).uniq
defaults = keys.map { |k| [k, nil] }.to_h
您可以尝试此代码:
combined = h1
.concat(h2)
.group_by { |a| a['name'] }
.values
.map do |a|
res = a.first.merge(a.last)
res['release'] ||= nil
res['url'] ||= nil
res
end
如果您不确定代码是什么,请尝试逐步执行。
首先,h1和h2是散列的数组,而不是散列本身。如果对它们进行迭代,得到的是数组中的每个散列,而不是某个散列的键和值。
为清楚起见,让我们将它们重命名为 a1
和 a2
。
a1= [{"name"=>"postgresql", "version"=>29}, {"name"=>"java", "version"=>8}, {"name"=>"python", "version"=>3}]
a2= [{"name"=>"postgresql", "release"=>"postgresql-release", "url"=>"https://github.com/repo/postgresql-release"}, {"name"=>"java", "release"=>"java-release", "url"=>"https://github.com/repo/java-release"}]
combined = []
现在,当我们迭代它们时,我们依次获得每个哈希。
a1.each do |h1|
对于第一个数组中的每个哈希,我们希望在第二个数组中找到相应的哈希。如果我们在第一个数组中查看java并在第二个数组中找到postgresql,这并不意味着没有java。我们只需要暂时忽略它。如果我们没有找到匹配项,那么我们将分配 nil-s
h2 = a2.find { |h| h1["name"] == h["name"] } || {}
现在我们已经找到了匹配项或没有找到匹配项,我们可以像您所做的那样将结果添加到组合数组中。
combined << {"name"=> h1["name"], "version"=> h1["version"], "release"=> h2["release"], "url"=> h2["url"]}
所有这些:
a1= [{"name"=>"postgresql", "version"=>29}, {"name"=>"java", "version"=>8}, {"name"=>"python", "version"=>3}]
a2= [{"name"=>"postgresql", "release"=>"postgresql-release", "url"=>"https://github.com/repo/postgresql-release"}, {"name"=>"java", "release"=>"java-release", "url"=>"https://github.com/repo/java-release"}]
combined = []
a1.each do |h1|
h2 = a2.find { |h| h1["name"] == h["name"] } || {}
combined << {"name"=> h1["name"], "version"=> h1["version"], "release"=> h2["release"], "url"=> h2["url"]}
end
puts combined.to_s #=> [{"name"=>"postgresql", "version"=>29, "release"=>"postgresql-release", "url"=>"https://github.com/repo/postgresql-release"}, {"name"=>"java", "version"=>8, "release"=>"java-release", "url"=>"https://github.com/repo/java-release"}, {"name"=>"python", "version"=>3, "release"=>nil, "url"=>nil}]
稍微简单一点的方法是使用map
。然后可以避免附加数组和手动追加
a1= [{"name"=>"postgresql", "version"=>29}, {"name"=>"java", "version"=>8}, {"name"=>"python", "version"=>3}]
a2= [{"name"=>"postgresql", "release"=>"postgresql-release", "url"=>"https://github.com/repo/postgresql-release"}, {"name"=>"java", "release"=>"java-release", "url"=>"https://github.com/repo/java-release"}]
combined = a1.map do |h1|
h2 = a2.find { |h| h1["name"] == h["name"] } || {}
{"name"=> h1["name"], "version"=> h1["version"], "release"=> h2["release"], "url"=> h2["url"]}
end
puts combined.to_s #=> [{"name"=>"postgresql", "version"=>29, "release"=>"postgresql-release", "url"=>"https://github.com/repo/postgresql-release"}, {"name"=>"java", "version"=>8, "release"=>"java-release", "url"=>"https://github.com/repo/java-release"}, {"name"=>"python", "version"=>3, "release"=>nil, "url"=>nil}]
另一个可能的改进是使用merge。
combined = a1.map do |h1|
h2 = a2.find { |h| h1["name"] == h["name"] } || { "release" => nil, "url" => nil}
h1.merge(h2)
end
我正在尝试使用Sinatra和BCrypt实现一种看似非常简单的身份验证方法,但显然我遗漏了一些东西... 用户会预先分配一个临时密码,该密码以明文形式存储在DB中。 我根据临时口令进行身份验证,然后创建salt和password_hash,并将它们作为字符串写入db(本例中为mongo)。 为了进行身份验证,我从db和用户口令中获取salt进行比较。 bcrypt::Engine.hash_se
我有两个哈希数组: 我想在< code>a2中找到其< code>ID和< code>name字段与< code>a1中条目的< code>ID和< code>name字段相匹配的散列(不考虑< code>email或任何其他进入< code>a2的项目),然后将< code>ORDER_NO的值合并到< code>a1散列中也就是说,以下列方式结束: 我也想忽略 a2 中存在的元素,但不忽略 a
我是powershell的新手。我想知道为什么下面的代码总是返回“false”: 什么时候 一个文件是另一个文件的副本 "get-filehash tn|selet-ject hash"为两个文件返回相同的值 两个文件都在同一个目录中 Tnx提前为您解答!
我使用mitsuhiko的pbkdf2实现进行密码哈希: 此函数返回二进制摘要,然后将其编码在bas64中并保存到数据库中。此外,当用户登录时,Base64字符串被设置为cookie。 此函数用于密码哈希比较: 我想知道在安全性方面,二进制哈希和Base64字符串的比较是否有任何不同?例如,当用户登录时,我会计算提交密码的二进制摘要,从数据库中解码Base64字符串,然后比较两个二进制哈希,但是如
嗨,我有两个哈希数组,如下所示 如何将它们合并到单个哈希数组中作为〔{“name”= 因为我需要根据哈希转换的管道分隔cucumber表来验证它们,例如|name|value|rihan|true||gihan|true| 对于cucumber表,我使用以下函数将其转换为哈希 对于实际的 JSON 响应,我正在使用递归函数将其提取到两个哈希数组 [A] 和 [B] 上方,但我不确定如何合并它们以与
有人能告诉我如何从WooCommerce网络钩子中重新创建哈希以与请求中的“X-WC-Webhook-Signature”标头哈希进行比较吗? 留档指定哈希是从“有效负载”生成的,但我无法生成相同的哈希。 我的API是。NET Core 3.1 我尝试的第一件事: 第二个: