【问题标题】:Merge different "type" lists合并不同的“类型”列表
【发布时间】:2011-12-21 12:12:57
【问题描述】:

我对 F# 比较陌生,但到目前为止,我对它印象深刻,尽管我花了很多时间搜索和查看我拥有的书籍,但我仍然找不到以下示例: 我有 3 个(实际上是更多)列表,它们是从不同的输入源创建的:数据库、CSV 文件等。假设这些列表的结构如下:

type L1 = {
    Id : int32   // Common id
    StringFieldA : string
    StringFieldB : string
}

type L2 = {
    Id : int32   // Common id
    Ratio: decimal
    StringFieldC : string
}

type L3 = {
    Id : int32    // Common id
    Mean: decimal
    StringFieldD : string
}

我有返回上述每个 F# 列表的方法。我现在希望将 3 个不同“类型”的列表合并为一个 - 基于公共 id - 到一个列表,如下所示:

type Merged = {
    Id : int32
    StringFieldA : string
    StringFieldB : string
    StringFieldC : string
    StringFieldD : string
    Mean: decimal
    Ratio: decimal
}

如何在 F# 中完成此操作?对不起,如果我错过了其他地方的样本。

【问题讨论】:

    标签: f# merge


    【解决方案1】:

    假设它们已排序且长度相等(如果不是这种情况,我不确定合并结果应该是什么):

    List.zip3 l1 l2 l3 |> List.map (fun (l1, l2, l3) ->
      { Id = l1.Id
        StringFieldA = l1.StringFieldA
        StringFieldB = l1.StringFieldB
        StringFieldC = l2.StringFieldC
        StringFieldD = l3.StringFieldD
        Mean = l3.Mean
        Ratio = l2.Ratio })
    

    【讨论】:

    • 是的 - 它们都经过排序并且长度完全相同 - 关于相同组织的数据,只是通过不同的输入接收到(不是我的设计......)
    • 谢谢丹尼尔,成功了。
    【解决方案2】:

    我认为这就是你想要的 - 一个有区别的工会

    type Data = 
        |First of L1
        |Second of L2
        |Third of L3
    

    然后您可以添加一个 Id 成员,例如

    with member x.Id = 
        match x with
        |First(a) -> a.Id
        |Second(a) -> a.Id
        |Third(a) -> a.Id
    

    【讨论】:

      【解决方案3】:

      如果所有列表都具有相同的 ID 集,也许您可​​以按 ID 对每个列表进行排序并将它们压缩在一起。

      【讨论】:

      • 我认为这不会满足他的要求——你最终会得到一个(L1 * L2 * L3) list。它还要求三个输入都具有相同的长度
      • 压缩不是最后一个操作,你还需要将元组映射成你想要的最终数据。
      猜你喜欢
      • 1970-01-01
      • 2016-08-14
      • 2019-06-09
      • 2015-04-10
      • 2022-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-27
      相关资源
      最近更新 更多