2016-03-31 9 views
10

Ich versuche, meine verschachtelten for-Schleifen zu einem funktionaleren Stil zu konvertieren.F # - Konvertieren geschachtelter for-Schleifen in einen funktionalen Stil

Ich habe mit Pipelining, Sequenzen und Arrays herumalbern, aber ohne Erfolg.

Hier ist, was ich habe:

let allCarrierCodes = new List<string>()  
for result in getAllCarrierCodesResults do 
     for carrierCode in result do 
      allCarrierCodes.Add(carrierCode.ToString()) 
  • getAllCarrierCodesResults ist ein seq vom Typ "OBJ-Liste"

Was ist eine schöne funktionelle Art und Weise der verschachtelten Schleifen neu zu schreiben?

Danke.

+0

Abgesehen davon, dass Sie die verschachtelte Schleife neu schreiben, sollten Sie von der "normalen" Liste ('System.Collections.Generic.List') zu F # Listen wechseln sind unveränderlich. Es gibt Ihnen Zugriff auf alle F # Goodies wie Pattern-Matching. Mit der folgenden Antwort von Lee wäre das "allCodes = getAllCarriesCodes |> Seq.concat |> Seq.map string |> List.ofSeq' –

Antwort

10

können Sie Seq.collect verwenden:

let allCodes = Seq.collect id getAllCarrierCodesResults 
       |> Seq.map string) 

oder

let allCodes = Seq.collect (Seq.map string) getAllCarrierCodesResults 

Sie dann die resultierende seq<string> in die Beton Sammlung Sie konvertieren kann.

+0

Anstatt" Seq.collect id "zu schreiben, würde ich' Seq.concat' verwenden . –

+0

Sie können auch die neue Funktion in F # 4 verwenden, wobei [Konstruktoren als erstklassige Funktionen verwendet werden können] (https://github.com/fsharp/FSharpLangDesign/blob/master/FSharp-4.0/ClassNamesAsFunctionsDesignAndSpec. md). Damit können Sie 'allCodes = getAllCarriesCodes |> Seq.concat |> Seq.map string |> List' schreiben. Für die Verwendung von List, siehe oben meinen Kommentar. –

8

Lee Antwort ist besser als das, aber ich wollte nur erwähnen, dass Sie völlig gerade in einer Liste Verständnis dieser verschachtelten Schleifen setzen, und voila:

let allCarrierCodes = 
    [for result in getAllCarrierCodesResults do 
    for carrierCode in result do 
     yield carrierCode.ToString()] 

Sieht irgendwie Imperativ-ish, aber ist wirklich funktional.

Außerdem sollten Sie string carrierCode anstelle von carrierCode.ToString() verwenden. Schützt Sie vor NRE und sieht funktioneller für zusätzlichen Bonus aus :-)

+0

Wenn Sie raten, '.ToString()' nicht zu verwenden, warum verwenden Sie es in Ihrer Antwort? – knocte

+0

Um es so nah wie möglich an den OP-Code zu halten. –

Verwandte Themen