我正在编写一个f#脚本来检查System.DirectoryServices.Principal对象是组还是用户。如果它是一个组,我必须递归地获取组中的用户列表,并且如果用户将用户作为列表返回。我写了以下函数
let rec getUserlist (p:Principal) =
match box p with
| :? UserPrincipal as u -> [u:>Principal]
| :? GroupPrincipal as g when g.IsSecurityGroup.HasValue && g.IsSecurityGroup.Value
-> g.GetMembers(false).ToArray()
|> Seq.map(fun p -> getUserlist p)
|> Seq.concat
|> Seq.toList
| _ -> []
此功能有效但对我来说看起来不太干净。我想知道是否有更好的方法来编写这个功能。
答案 0 :(得分:2)
您不需要将其设置为对类型进行模式匹配,使用下载变量u
仅将其再次向上播放是没有意义的。
另请注意,map
然后concat
为collect
,您正在转换为数组,然后列出...更好地使用seq
并获得所有结果在呼叫站点将其转换为您想要的任何内容。
let rec getUserlist (p:Principal) =
match p with
| :? UserPrincipal -> Seq.singleton p
| :? GroupPrincipal as g when g.IsSecurityGroup.HasValue && g.IsSecurityGroup.Value
-> g.GetMembers false |> Seq.collect getUserlist
| _ -> Seq.empty
如果您愿意,可以使用序列表达式:
let rec getUserlist (p:Principal) = seq {
match p with
| :? UserPrincipal as u -> yield p
| :? GroupPrincipal as g when g.IsSecurityGroup.HasValue && g.IsSecurityGroup.Value
-> for p in g.GetMembers false do
yield! getUserlist p
| _ -> ()}