Mat*_*ews 5 f# dictionary f#-data
这个问题来自于正在努力从R转换到F#的人.我完全承认我的方法可能是错的,所以我正在寻找F#这样做的方法.我有一种情况,我想迭代一组XML文件,解析它们,并提取几个值,以确定哪些需要进一步处理.我的自然倾向是映射XML数据数组,exampleData在这种情况下,使用RawDataProvider类型提供程序解析每个数据,最后为包含解析的XML,XML中的Status值和ItemId值的每个文件创建一个Map对象.
事实证明,F#中的Map类型与R中的List不同.R中的列表本质上是可以支持混合类型的哈希映射.看来F#中的Map类型不支持存储混合类型.我发现这在我的R工作中非常有用,我正在寻找合适的F#系列.
或者,我是否认为这一切都错了?这是我在R中处理数据的一种非常自然的方式,所以我希望有一种方法可以在F#中进行处理.假设我将进行进一步分析并向这些集合添加其他数据元素.
更新: 这似乎是一个简单的用例,必须有一种惯用的方式在F#中执行此操作,而无需为每个分析步骤定义记录类型.我已经更新了我的例子,以进一步说明我想要做的事情.我想返回我分析的Map对象数组:
type RawDataProvider = XmlProvider<"""<product Status="Good" ItemId="123" />""">
let exampleData = [| """<product Status="Good" ItemId="123" />"""; """<product Status="Bad" ItemId="456" />"""; """<product Status="Good" ItemId="789" />"""|]
let dataResult =
exampleData
|> Array.map(fun fileData -> RawDataProvider.Parse(fileData))
|> Array.map(fun xml -> Map.empty.Add("xml", xml).Add("Status", xml.Status).Add("ItemId", xml.ItemId))
|> Array.map(fun elem -> elem.["calc1Value"] = calc1 elem["itemId"])
|> Array.map(fun elem -> elem.["calc2"] = calc2 elem.["ItemId"] elem.["calc1Value"])
Run Code Online (Sandbox Code Playgroud)
这就是我在这里认为几乎惯用的 - 我保持与您的示例中相同的形状,以便您可以匹配两者:
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)
Run Code Online (Sandbox Code Playgroud)
真正XmlProvider为您提供的不仅仅是 xml 解析,而是它生成 xml 的强类型表示形式。这比将数据放入映射中更好,因为它可以为您提供更有力的保证,让您知道您的程序是否在做正确的事情。例如,它不会让你混淆itemId,ItemId就像你的代码片段中发生的那样;)
对于在以下步骤中计算的值,您可以使用元组而不是记录。一般来说,记录比元组更受欢迎,因为它们可以产生更可读的代码,但是将不同类型的相关值组合到临时聚合中确实是使用元组的最佳场景。
现在,我说的几乎是惯用的 - 我会将解析和处理已解析的 xml 分解为单独的函数,并在单个函数中计算和calc1结果calc2,而不是像Array.maps这样组合两个:
let dataResult =
parsedData
|> Array.map(fun xml ->
let calced1 = calc1 xml.ItemId
xml, calced1, calc2 xml.ItemId calced1)
Run Code Online (Sandbox Code Playgroud)
如果您有 R 背景,您可能需要查看Deedle以获取替代方法。它为您提供了类似于 F# 中的 R 的工作流程。
| 归档时间: |
|
| 查看次数: |
521 次 |
| 最近记录: |