我已经做了perl很长一段时间了,因此这让我感到困惑ruby。我收集了来自不同地方的数据,并希望提供以下格式:
{
:"user_100" => {
:user_policy => [
"userpolicy_100",
"userpolicy_200"
],
:group_policy => [
"grouppolicy_300",
"grouppolicy_400"
],
},
:"user_200" => {
:user_policy => [
"userpolicy_300",
"userpolicy_400"
],
:group_policy => [
"grouppolicy_300",
"grouppolicy_400"
],
},
}
上面的结构是数组哈希的哈希,我只是无法在ruby中使用它。顺便说一句,我手动编写了上面的代码,因此可能存在语法错误。
我试过了:
hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
但这只有在我有nested hashes
和no array
的情况下才有效。
然后我尝试了:
hash = Hash.new{ |h,k| h[k] = [] }
但这仅适用于hash of arrays
,而不适用于hash of hash of array
。
我需要在一个地方捕获这些数据,我想象它会按照上面的代码片段显示。
问题:
hash of hash of array
?更新
这是我的实际代码:
array_users = Array.new
hash_user_polices = Hash.new{ |h,k| h[k] = [] }
iam = Aws::IAM.new
iam.list_users().each do |resp|
resp.users.each do |x|
array_users << x.user_name
end
end
array_users.each do |user|
iam.list_user_policies(:user_name => user).each do |resp|
resp.each do |x|
x.policy_names.each do |y|
hash_user_polices[:"#{user}"] << y.to_s
end
end
end
end
所以,
我获取了用户列表并将其放入array_users
。然后我得到相应的用户政策,这些政策以array
的形式返回(因此我正在迭代x.policy_names.each do |y|
)。
我真的很想hash_user_polices[:"#{user}"][:user_policy] << y.to_s
。
但由于我在ruby方面的专业知识有限,我只能在hash_user_polices[:"#{user}"] << y.to_s
定义hash_user_polices = Hash.new{ |h,k| h[k] = [] }
之后才能使其工作。
我将编写一段单独的代码来获取group_policies,因此在那时,我希望它有hash_user_polices[:"#{user}"][:group_policy] << y.to_s
。
简而言之,我在三个不同的API调用中提取user list
,user policy
和group policy
,并努力在一个地方合并这三个,以便我能够理解它的。
答案 0 :(得分:1)
你可以这样做(但不知道你的数据是如何构建的,很难说)
iam = Aws::IAM.new
array_users = iam.list_users.map(&:users).flatten.map(&:user_name)
Hash[
array_users.map do |user|
[
user.to_sym,
{ user_policy: iam.list_user_policies(:user_name => user).map(&:resp).flatten.map(&:policy_names).flatten.map(&:to_s),
group_policy: <group_policy logic>
}
[
end
end ]
答案 1 :(得分:1)
如果结构总是hash.hash.array,您可以使用两次尝试的组合:
hash = Hash.new do |oh,ok|
oh[ok] = Hash.new do |ih,ik|
ih[ik] = []
end
end
我个人不会使用哈希和阵列来做这件事; ruby有一个非常强大的对象模型,我会为每个嵌套级别创建类(特别是“用户”级别,它似乎有一组明确定义的属性)。不过,你可能会觉得有点矫枉过正。
答案 2 :(得分:1)
如果你的代码变得容易理解,你可以将代码拆分成更容易理解的东西吗?
def add_policy(hash, user, policy)
# create a subhash for the user key if the hash doesn't exist
hash[user] ||= {}
# get the policy key: :group_policy or :user_policy
# if policy_key can not be determined from the policy,
# you could pass an extra param for the policy_key
policy_key = ( policy.include?("group") ? :group_policy : :user_policy )
# create an array for the user's policy if none exists
hash[user][policy_key] ||= []
# push the policy into the array
hash[user][policy_key] << policy
hash
end
h = {}
add_policy(h, "user_100", "userpolicy_100")
add_policy(h, "user_100", "userpolicy_200")
add_policy(h, "user_100", "grouppolicy_300")
add_policy(h, "user_100", "grouppolicy_400")
add_policy(h, "user_200", "userpolicy_300")
add_policy(h, "user_200", "userpolicy_400")
add_policy(h, "user_200", "grouppolicy_300")
add_policy(h, "user_200", "grouppolicy_400")
=> {"user_100"=>
{:user_policy=>["userpolicy_100", "userpolicy_200"],
:group_policy=>["grouppolicy_300", "grouppolicy_400"]},
"user_200"=>
{:user_policy=>["userpolicy_300", "userpolicy_400"],
:group_policy=>["grouppolicy_300", "grouppolicy_400"]}}
答案 3 :(得分:0)
require 'xkeys'
r={}.extend XKeys::Auto
r[:user_100, :user_policy, :[]] = 'userpolicy_100'
r[:user_100, :user_policy, :[]] = 'userpolicy_200'
r[:user_100, :group_policy, :[]] = 'grouppolicy_300'
r[:user_100, :group_policy, :[]] = 'grouppolicy_400'
r[:user_200, :user_policy, :[]] = 'userpolicy_300'
r[:user_200, :user_policy, :[]] = 'userpolicy_400'
r[:user_200, :group_policy, :[]] = 'grouppolicy_300'
r[:user_200, :group_policy, :[]] = 'grouppolicy_400'
p r
# {
# :user_100=>{
# :user_policy=>["userpolicy_100", "userpolicy_200"],
# :group_policy=>["grouppolicy_300", "grouppolicy_400"]
# },
# :user_200=>{
# :user_policy=>["userpolicy_300", "userpolicy_400"],
# :group_policy=>["grouppolicy_300", "grouppolicy_400"]
# }
# }