Получение пользователей Active Directory и прохождение через них для возврата нового списка с помощью F # - PullRequest
1 голос
/ 21 января 2020

Я пробовал несколько способов заставить это работать, я думаю, что мне нужна какая-то рекурсивная функция, но я не смог обернуть ее вокруг. Посмотрел на складки и катаморфизм и не совсем понял, как я могу применить это в этой ситуации. Я также попробовал пример с 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

1 Ответ

2 голосов
/ 21 января 2020

У меня нет Active Directory, поэтому я не смог проверить это. Тем не менее, одна строка в вашем коде, которая определенно неверна, следующая:

results |> List.append <| a |> ignore

Я полагаю, вы пытаетесь добавить новое значение a в список results, но F # списки являются неизменяемыми, так что это просто создает новый список и затем игнорирует его, используя ignore.

Использование списочных представлений, как вы пытались в закомментированной версии, безусловно, является одним из хороших способов добиться этого. Правильный синтаксис, включающий ваш код 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 не возвращает обобщенный c 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())
...