在F#中串联列表的列表

时间:2019-05-20 20:54:21

标签: list f#

从伪C#中,我有这个:

class C
{
   List<A> a;
   List<B> b;
}

List<C> L;

我想得到两个列表:ListA和ListB,其中ListA是列表L中所有'a'字段的串联,对于ListB类似。

那会是这样的:

var ListA = new List<A>();
var ListB = new List<B>();
foreach (var l in L)
{
    ListA.Append(l.a);
    ListB.Append(l.b);
} 

在F#中, 我假设它是这样的:let ListA = L |> List.Concat(但是我怎么说要选择字段a?)

还是可以作为let ListA = L |> List.Fold (fun acc value -> acc.Concat value)完成(我如何在此处指定空白列表?)

或者,可以这样做吗?

let getElementsA (l : C list) =
    seq {
        for element in l do
            for a in element.a do
                yield a
    }

但这不是太冗长吗?

3 个答案:

答案 0 :(得分:3)

这是List.collect或C#列表的Seq.collect的作用:

let listA = l |> Seq.collect (fun element -> element.a) |> List.ofSeq
let listB = l |> Seq.collect (fun element -> element.b) |> List.ofSeq

或者如果您真的需要在一次迭代中执行此操作,则可以使用折叠:

let (seqA, seqB) =
  l |> Seq.fold
         (fun (seqA, seqB) element -> (Seq.append element.a seqA, Seq.append element.b seqB))
         ([], [])

答案 1 :(得分:3)

您可以使用List.collect

let getElementsA (cs : C list) = cs |> List.collect (fun c -> c.a)

如果属性类型为System.Collection.List<T>,则可以使用Seq.collect

let getElementsA (cs : C list) = cs |> Seq.collect (fun c -> c.AS)

这将返回一个A seq,您可以使用List.ofSeq将其转换为列表:

let getElementsA (cs : C list) = cs |> Seq.collect (fun c -> c.AS) |> List.ofSeq

答案 2 :(得分:1)

F#使用其他列表,函数对象(例如委托)。您可以在Microsoft.FSharp命名空间中找到所有需要的内容


如果我在F#中有此代码。 该函数可对带有操作的列表进行排序,但不返回任何内容(list:'a list -> action:('a -> unit) -> unit)。

module FS =
    let actLit list action =
        list
        |> List.iter (action)

为此,在C#上包括Microsoft.FSharp.Collections.ListModule模块,并且调用函数可与F#列表一起使用。 ListModule.OfSeq(l)创建新的F#列表。

Microsoft.FSharp.Core.FunctionModule包含转换方法。

转换后可以调用它。

var a = new List<int> ();
var list = ListModule.OfSeq(a);
var func = FuncConvert.FromAction<int>(Console.WriteLine);

FS.actLit(list, func);