2016-03-31 14 views
10

Próbuję konwertować zagnieżdżone pętle for do bardziej funkcjonalnego stylu.F # - Konwersja zagnieżdżonych pętli for do stylu funkcjonalnego

Zmywałem z pipelining, sekwencji i tablic, ale bez skutku.

Oto co mam:

let allCarrierCodes = new List<string>()  
for result in getAllCarrierCodesResults do 
     for carrierCode in result do 
      allCarrierCodes.Add(carrierCode.ToString()) 
  • getAllCarrierCodesResults jest nast typu "obj liście"

Co to miły funkcjonalny sposób, aby ponownie napisać zagnieżdżone pętle?

Dzięki.

+0

Oprócz ponownego zapisu zagnieżdżonej pętli, rozważ przejście z "normalnej" listy ('System.Collections.Generic.List') na listę F #, która są niezmienne. Da ci dostęp do wszystkich gadżetów F #, takich jak dopasowywanie wzorców. Z poniższą odpowiedzią Lee byłoby to "niech allCodes = getAllCarriesCodes |> Seq.concat |> ciąg Seq.map |> List.ofSeq' –

Odpowiedz

10

Można użyć Seq.collect:

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

lub

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

można następnie przekonwertować wynikowy seq<string> w betonowym kolekcji chcesz.

+0

Zamiast pisać' Seq.collect id', użyłbym 'Seq.concat' . –

+0

Możesz także skorzystać z nowej funkcji w F # 4, gdzie [konstruktory mogą być używane jako funkcje najwyższej klasy] (https://github.com/fsharp/FSharpLangDesign/blob/master/FSharp-4.0/ClassNamesAsFunctionsDesignAndSpec. md). Dzięki temu możesz napisać: "let allCodes = getAllCarriesCodes |> Seq.concat |> ciąg Seq.map |> Lista' Aby użyć listy, zobacz mój komentarz powyżej. –

8

Lee Odpowiedź jest lepsze niż to, ale chciałem tylko wspomnieć, że można całkowicie wystarczy umieścić te zagnieżdżone pętle wewnątrz listowego i voila:

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

Wygląda rodzaju imperatyw-owski, ale jest naprawdę funkcjonalny.

Należy również użyć string carrierCode zamiast carrierCode.ToString(). Chroni Cię przed NRE i wygląda bardziej funkcjonalnie na dodatkowy bonus :-)

+0

jeśli radzisz nie używać '.ToString()', dlaczego używasz go w swojej odpowiedzi? – knocte

+0

Aby zachować go jak najbliżej kodu OP. –