方法:get_users_in_groups(groupname) 目的:获取来自组和任何嵌套组的所有成员'成员。
方法的英文翻译:
get group information
if group has members,
add members to users[]
end
If group has nested_groups,
for nested_group in nested_groups
get nested_groupname
get_users_in_groups(nested_groupname)
end
end
目前我在方法属性中传递users数组。但是,这似乎不是在递归方法中访问数组的正确方法。
通过递归方法将成员添加到users数组的最佳方法是什么?
我想我可能找到了解决方案。
users = []
get group information
if group has members,
users.concat( members[] )
end
If group has nested_groups,
for nested_group in nested_groups
get nested_groupname
users.concat( get_users_in_groups(nested_groupname) )
end
end
users.uniq
这是最好的方法吗?
很抱歉,我打算加一个!
ISC-人员 嵌套组:isc-admins,isc-teachers,isc-paras 成员:无
ISC-管理员 嵌套组:无 成员:adminone,admintwo
ISC-教师 嵌套组:加速教师 成员:teacherone,teachertwo
ISC-第 嵌套组:无 成员:paraone,paratwo
加速教师 嵌套组:无 成员:spedteacherone,spedteachertwo
所以我的方法查找isc-staff,看到它有isc-admins,isc-teachers和isc-paras但没有成员,它需要在isc-admins,isc-teachers和isc-paras上运行。 当它在isc-admins上运行时,它应该将成员添加到用户[] 当它在isc-teachers上运行时,它应该将成员添加到users []并通过sped-teachers运行自己
此信息不存储在数组中,必须从LDAP中提取。
这有足够的信息吗?
结构与
类似{
group_name: 'isc-staff',
nested_groups: [
{
group_name: 'isc-admins',
members: ['adminone', 'admintwo']
},
{
group_name: 'isc-teachers',
members: ['teacherone', 'teachertwo'],
nested_groups: [
{
group_name: 'sped-teachers',
members: ['spedteacherone']
}
]
},
{
group_name: 'isc-paras',
members: ['paraone', 'paratwo']
}
]
}
结果应该是:
['adminone','admintwo','teacherone','teachertwo','spedteacherone','paraone','paratwo']
答案 0 :(得分:0)
我的解决方案很普遍。您的结构可以是数组或散列,递归地包含任何深度的数组,散列和文字。我假设你想要的值是数组中的字符串,并且所有数组都不包含字符串或只包含字符串(尽管那些不包含字符串的字符串可能包含嵌套的字符串数组,可以找到它们。)
<强>代码强>
def getem(e,a=[])
case e
when Array
case e.first
when String
e.each { |f| a << f }
else
e.each do |f|
case f
when Array, Hash
getem(f,a)
end
end
end
when Hash
e.each { |_,v| getem(v,a) }
end
a
end
示例强>
h = {
group_name: 'isc-staff',
nested_groups:
[
{
group_name: 'isc-admins',
members: ['adminone', 'admintwo']
},
{
group_name: 'isc-teachers',
members: ['teacherone', 'teachertwo'],
nested_groups:
[{
group_name: 'sped-teachers',
members: ['spedteacherone']
}]
},
{
group_name: 'isc-paras',
members: ['paraone', 'paratwo']
}
]
}
getem(h)
#=> ["adminone", "admintwo", "teacherone", "teachertwo",
# "spedteacherone", "paraone", "paratwo"]
(请注意,您在示例哈希中犯了几个小错误。)
<强>解释强>
getem
是数组或散列时,会调用 e
。返回值是数组a
,在首次调用getem
时默认为空数组。
我们使用case
语句来测试对象的类。这是有效的,因为案例使用Object#===而不是==
来确定true
或false
。
如果getem
的第一个参数是一个数组,我们看看第一个元素是否是一个字符串。如果是,我们假设所有元素都是字符串,并将它们添加到数组a
。否则,我们递归调用getem
作为数组或散列的每个元素。
如果getem
的第一个参数是散列,我们递归调用getem
作为数组或散列的每个值。 (由于我们不在块中使用散列键,因此我们可以编写|_v|
而不是|k,v|
)。
答案 1 :(得分:0)
假设您的数据结构是带有符号键的哈希,一个简单的递归函数可以解决这个问题:
def all_group_members group
members = []
members.concat group[:members] if group[:members]
if group[:nested_groups]
group[:nested_groups].each { |g| members.concat all_group_members(g) }
end
members
end
答案 2 :(得分:0)
根据我过去几天对递归查询的了解,我提出了这种方法。这有用吗?
def self.get_users_in_group(groupname)
users = []
if exists?(groupname)
params = [
"GroupMembership",
"NestedGroups"
]
DSQuery.generate_dscl("read","/Groups/#{groupname}",params)
output = DSQuery.run
# Add members of group to users array.
if output.has_key?('dsAttrTypeStandard:GroupMembership')
users.concat(output['dsAttrTypeStandard:GroupMembership'])
end
# if group contains nested groups,
# get_users_in_group for each nested group and add to users array.
if output.has_key?('dsAttrTypeStandard:NestedGroups')
output['dsAttrTypeStandard:NestedGroups'].each do |generate_dscldUID|
results = find('GeneratedUID',generate_dscldUID)
if !results.empty?
result = results[0]
length_of_nested_group_name = result.index("\t") - "\t".length
nested_group_name = result.slice(0..length_of_nested_group_name)
users.concat( get_users_in_group(nested_group_name) )
end
end
end
end
users.uniq
end