在 F# 中通过公共 ID 将多个数据列表合并在一起 [英] Merge multiple lists of data together by common ID in F#

查看:8
本文介绍了在 F# 中通过公共 ID 将多个数据列表合并在一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有来自 4 个不同来源的多个数据列表,其中包含一组通用 ID,我想根据 ID 将这些数据合并在一起,最终得到一个新列表,每个 ID 一个,每个源一个条目.

I have multiple lists of data from 4 different sources with a common set of IDs that I would like to merge together, based on ID, basically ending up with a new list, one for each ID and a single entry for each source.

来自 4 个源中的每一个的输出列表中的对象如下所示:

The objects in the output list from each of the 4 sources look something like this:

type data = {ID : int; value : decimal;}

所以,例如我会:

let sourceA = [data1, data2, data3];
let sourceB = [data1, data2, data3];
let sourceC = [data1, data2, data3];
let sourceD = [data1, data2, data3];

(我意识到这段代码无效,只是想给出一个基本的想法……这些列表实际上是从数据库中提取和生成的)

(I realize this code is not valid, just trying to give a basic idea... the lists are actually pulled and generated from a database)

然后我想将 sourceA、sourceB、sourceC 和 sourceD 处理成一个包含如下对象的列表:

I would then like to take sourceA, sourceB, sourceC and sourceD and process them into a list containing objects something like this:

type dataByID = {ID : int; valueA : decimal; valueB : decimal; valueC : decimal; valueD : decimal; }

...这样我就可以将它们打印在 CSV 中,第一列是 ID,而 coulmns 2 - 5 是来自与该行中的 ID 相对应的源 A - D 的数据.

...so that I can then print them out in a CSV, with the first column being the ID and coulmns 2 - 5 being data from sources A - D corresponding to the ID in that row.

我对 F# 完全陌生,那么处理这些数据的最佳方法是什么,以便我按 ID 匹配所有源数据值??

I'm totally new to F#, so what would be the best way to process this data so that I match up all the source data values by ID??

推荐答案

看来你可以简单地连接所有列表,然后使用 Seq.groupBy 来获取包含唯一 ID 的列表输入列表以及与 ID 关联的所有值.这可以使用以下方法完成:

It seems that you could simply concatenate all the lists and then use Seq.groupBy to get a list that contains unique IDs in the input lists and all values associated with the ID. This can be done using something like:

let data = 
  [ data1; data2; data3; data4 ]   // Create list of lists of items 
  |> Seq.concat                    // Concatenate to get a single list of items
  |> Seq.groupBy (fun d -> d.ID)   // Group elements by ID

seq { for id, values in data -> 
        // ID is the id and values is a sequence with all values 
        // (that come from any data source) }

如果您想将源(无论是data1data2等...)与值相关联,那么您可以先使用map`操作添加数据源的索引:

If you want to associate the source (whether it was data1, data2, etc...) with the value then you can first usemap` operation to add an index of the data source:

let addIndex i data = 
  data |> Seq.map (fun v -> i, v)

let data = 
  [ List.map (addIndex 1) data1;
    List.map (addIndex 2) data2;
    List.map (addIndex 3) data3;
    List.map (addIndex 4) data4 ]
  |> Seq.concat
  |> Seq.groupBy (fun (index, d) -> d.ID)

现在,data 还包含数据源的索引(从 1 到 3),因此在对值进行迭代时,您可以使用索引找出该项来自哪个数据源.可以使用 Seq.mapi 编写更好的版本来迭代数据源列表并自动为所有值添加索引:

Now, data also contains index of the data source (from 1 to 3), so when iterating over the values, you can use index to find out from which data source the item comes from. Even nicer version can be written using Seq.mapi to iterate over list of data sources and add index to all the values automatically:

let data = 
  [ data1; data2; data3; data4 ]
  |> Seq.mapi (fun index data -> Seq.map (addIndex index) data)
  |> Seq.concat
  |> Seq.groupBy (fun (index, d) -> d.ID)

这篇关于在 F# 中通过公共 ID 将多个数据列表合并在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆