Объединение списков списков в F # - PullRequest
1 голос
/ 20 мая 2019

Из псевдо C #, у меня есть это:

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

List<C> L;

Я хотел бы получить два списка: ListA и ListB, где ListA - это объединение всех полей 'a' из списка L и аналогично для 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 ]

3 голосов
/ 21 мая 2019

Вы можете использовать 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
3 голосов
/ 21 мая 2019

Это то, что List.collect, или Seq.collect для списков C #, предназначено для:

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 голос
/ 21 мая 2019

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); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...