Я думаю, что все ответы, опубликованные ранее, дают хорошее решение. Интересно, что это не то, что может быть элегантно решено с помощью выражений последовательности F # - вы должны использовать списки и рекурсию, некоторые хитрые функции (например, pairwise
) или использовать интерфейс IEnumerator
.
Я написал конструктор вычислений, который позволяет вам работать с IEnumerator
(см. Полный исходный код на fssnip.net ). Используя это вычисление, вы можете решить его очень красиво:
let loadFile path =
// Recursive function that generates IEnumerator of key * value pairs
let rec loop source = iter {
// Read key & value and continue if both are available
let! key = source
let! value = source
match key, value with
| Some key, Some value ->
// Produce key * value pair and continue looping
yield key, value
yield! loop source
| _ -> () }
// Create sequence that reads data and convert it to dictionary
Enumerator.toSeq (fun () ->
loop (File.ReadAllLines(@"keyvalue.txt").GetEnumerator())) |> dict
Я считаю вычисления iter
очень хорошими - в некоторых случаях вы не можете решить проблему с помощью F # seq
. Тогда вы можете использовать рекурсию и списки - но тот же самый шаблон рекурсии может быть также написан довольно аккуратно, используя iter
.