Here's what I find almost idiomatic here - I stick to the same form as in your example so that you can match two:
let dataResult = exampleData |> Array.map(fun fileData -> RawDataProvider.Parse(fileData)) |> Array.map(fun xml -> xml, calc1 xml.ItemId) |> Array.map(fun (xml, calcedValue1) -> xml, calcedValue1, calc2 xml.ItemId calcedValue1)
What XmlProvider
really gives you is not just xml parsing, but the fact that it generates a strongly typed xml representation. This is better than transferring data to a card, as it gives you more reliable guarantees regarding the correctness of your program. For example, this will not allow you to mix itemId
and itemId
, as it was in the code snippet;)
For the values ββthat you calculate in the next steps, you can use tuples instead of writing. In general, records are preferable to tuples, since they lead to more readable code, but combining related values ββof different types into special aggregates is really a script that uses syntax code.
Now I said almost idiomatically - I would decompose the parsing and processing of the processed xmls into separate functions, and calculate both calc1
and calc2
leads to one function instead of compiling two Array.maps
as follows:
let dataResult = parsedData |> Array.map(fun xml -> let calced1 = calc1 xml.ItemId xml, calced1, calc2 xml.ItemId calced1)
If you come from background R, you can check out Deedle for an alternative approach. It gives you a workflow similar to R in F #.
source share