使用 F# 获取 Active Directory 用户并通过它们循环到 return 一个新列表
Getting Active Directory Users and looping through them to return a new list using F#
我已经尝试了几种方法来让它工作,我想我需要某种递归函数,但一直无法理解它。看了看褶皱和变质现象,并没有真正理解我如何在这种情况下应用它。我也尝试了 yeild 的例子。
这是我目前的代码:
//Function: Get AD User Directory Services
let getADUserDS (searchBase:string,filter:string) =
let dEntry = new DirectoryEntry("LDAP://"+searchBase)
let propertiesToLoad = [|"samaccountname"|]
let dSearcher = new DirectorySearcher(dEntry,filter,propertiesToLoad)
let searchResults = dSearcher.FindAll()
let results: String List = []
//let newSearchResults = [for u in searchResults do let r = u.GetDirectoryEntry() && let a: String List = [r.Properties.["samaccountname"].Value.ToString()] && yeild a]
//let results = newSearchResults |> List.filter ((<>) "")
for u in searchResults do
match u with
| null -> printfn ""
| u when u.ToString() = ""-> printfn ""
| _ -> let r = u.GetDirectoryEntry()
let a: String List = [r.Properties.["samaccountname"].Value.ToString()]
results |> List.append <| a |> ignore
results
我没有可用的 Active Directory,因此无法对此进行测试。但是,您的代码中绝对不正确的一行是以下一行:
results |> List.append <| a |> ignore
我想您正在尝试将新值 a
添加到 results
的列表中,但是 F# 列表是不可变的,因此这只是创建一个新列表,然后使用 [= 忽略它15=].
在注释掉的版本中尝试使用列表理解绝对是解决此问题的一种好方法。包含您的 match
代码的正确语法是:
let newSearchResults =
[ for u in searchResults do
match u with
| null -> printfn ""
| u when u.ToString() = ""-> printfn ""
| _ -> let r = u.GetDirectoryEntry()
yield r.Properties.["samaccountname"].Value.ToString() ]
或者,您可以使用 List.map
和 List.filter
等函数。需要注意的是 dSearcher.FindAll
不会返回泛型 IEnumerabl
,因此您需要做一些额外的工作才能将此结果转换为普通的 F# 列表 - 一个简单的列表理解可以很好地为您做到这一点:
let searchResults = [ for r in dSearcher.FindAll() -> r ]
let newSearchResults =
searchResults
|> List.filter (fun u -> u <> null && u.ToString() <> "")
|> List.map (fun u ->
let r = u.GetDirectoryEntry()
r.Properties.["samaccountname"].Value.ToString())
我已经尝试了几种方法来让它工作,我想我需要某种递归函数,但一直无法理解它。看了看褶皱和变质现象,并没有真正理解我如何在这种情况下应用它。我也尝试了 yeild 的例子。
这是我目前的代码:
//Function: Get AD User Directory Services
let getADUserDS (searchBase:string,filter:string) =
let dEntry = new DirectoryEntry("LDAP://"+searchBase)
let propertiesToLoad = [|"samaccountname"|]
let dSearcher = new DirectorySearcher(dEntry,filter,propertiesToLoad)
let searchResults = dSearcher.FindAll()
let results: String List = []
//let newSearchResults = [for u in searchResults do let r = u.GetDirectoryEntry() && let a: String List = [r.Properties.["samaccountname"].Value.ToString()] && yeild a]
//let results = newSearchResults |> List.filter ((<>) "")
for u in searchResults do
match u with
| null -> printfn ""
| u when u.ToString() = ""-> printfn ""
| _ -> let r = u.GetDirectoryEntry()
let a: String List = [r.Properties.["samaccountname"].Value.ToString()]
results |> List.append <| a |> ignore
results
我没有可用的 Active Directory,因此无法对此进行测试。但是,您的代码中绝对不正确的一行是以下一行:
results |> List.append <| a |> ignore
我想您正在尝试将新值 a
添加到 results
的列表中,但是 F# 列表是不可变的,因此这只是创建一个新列表,然后使用 [= 忽略它15=].
在注释掉的版本中尝试使用列表理解绝对是解决此问题的一种好方法。包含您的 match
代码的正确语法是:
let newSearchResults =
[ for u in searchResults do
match u with
| null -> printfn ""
| u when u.ToString() = ""-> printfn ""
| _ -> let r = u.GetDirectoryEntry()
yield r.Properties.["samaccountname"].Value.ToString() ]
或者,您可以使用 List.map
和 List.filter
等函数。需要注意的是 dSearcher.FindAll
不会返回泛型 IEnumerabl
,因此您需要做一些额外的工作才能将此结果转换为普通的 F# 列表 - 一个简单的列表理解可以很好地为您做到这一点:
let searchResults = [ for r in dSearcher.FindAll() -> r ]
let newSearchResults =
searchResults
|> List.filter (fun u -> u <> null && u.ToString() <> "")
|> List.map (fun u ->
let r = u.GetDirectoryEntry()
r.Properties.["samaccountname"].Value.ToString())