从伪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
}
但这不是太冗长吗?
答案 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);