4

我是 F# 的新手,想知道如何将列表展平。

本质上,我在数据库中存储了一条具有 min_age 和 max_age 范围的记录(为了简洁起见,这是一个虚构的例子——我不是 agist!)。我的字段如下所示:

id、成本、储蓄、min_age、max_age

我基本上有一个 F# 类,它充当与该表的一对一映射 - 即所有属性都精确映射到数据库字段。

我想做的是使这个范围变平。所以,而不是包含这样的项目的列表:

saving_id = 1, cost = 100, savings = 20, min_age = 20, max_age = 26
saving_id = 2, cost = 110, savings = 10, min_age = 27, max_age = 31

我想要一个包含以下项目的列表:

saving_id = 1, cost = 100, savings = 20, age = 20
saving_id = 1, cost = 100, savings = 20, age = 21
etc.
saving_id = 2, cost = 110, savings = 10, age = 27
saving_id = 2, cost = 110, savings = 10, age = 28
etc.

是否有任何内置机制以这种方式展平列表和/或有人知道如何实现这一点?提前致谢,

J.P

4

2 回答 2

8

您可能想要使用 Seq.collect。它将序列连接在一起,因此在您的情况下,您可以在输入上映射一个函数,将单个年龄范围记录拆分为一系列年龄记录,并使用 Seq.collect 将它们粘合在一起。

例如:

type myRecord =
{ saving_id: int;
  cost: int;
  savings: int;
  min_age: int;
  max_age: int }

type resultRecord =
    { saving_id: int;
      cost: int;
      savings: int;
      age: int }

let records = 
    [ { saving_id = 1; cost = 100; savings = 20; min_age = 20; max_age = 26 }
      { saving_id = 2; cost = 110; savings = 10; min_age = 27; max_age = 31 } ]

let splitRecord (r:myRecord) =
    seq { for ageCounter in r.min_age .. r.max_age -> 
            { saving_id = r.saving_id;
              cost = r.cost;
              savings = r.savings;
              age = ageCounter }
    }

let ageRanges = records |> Seq.collect splitRecord

编辑:您还可以使用带有产量的序列生成器!

let thisAlsoWorks = 
    seq { for r in records do yield! splitRecord r }  
于 2010-10-25T06:37:24.380 回答
1

同意 cfern 的回答,但想知道这是否会从使用另一个“内置”功能中受益。这是该函数的另一个版本,splitRecord它显示了用于展开序列的库调用。除了有一个例子之外,这里没有任何收获Seq.unfold

let splitRecord (r:myRecord) = 
    Seq.unfold (fun curr_age ->
                    if curr_age <= r.max_age then
                        Some({  saving_id = r.saving_id; 
                                cost = r.cost; 
                                savings = r.savings; 
                                age = curr_age } ,
                                curr_age + 1) 
                    else None)
                r.min_age
于 2010-10-25T11:08:23.853 回答