通过 f# 中的展平将数组的数组缩减为单个数组

Noe*_*oel 3 f#

如果我有以下内容

type Merchant = {
    Id:int;
    OtherItems:int[] }


let (merchant1:Merchant) = {
    Id = 1;
    OtherItems = [| 1; 2 |]}

let (merchant2:Merchant) = {
    Id = 2;
    OtherItems = [| 1; 2 |]}


let merchants = [| merchant1;merchant2|]
Run Code Online (Sandbox Code Playgroud)

我想扁平化到以下,我该怎么做?

Id = 1 OtherItems 1  
Id = 1 OtherItems 2 
Id = 2 OtherItems 1  
Id = 2 OtherItems 2
Run Code Online (Sandbox Code Playgroud)

这是我想出的,但似乎无法进一步

let x = 
    merchants
     |> Array.map(fun merchant -> merchant, merchant.OtherItems)
Run Code Online (Sandbox Code Playgroud)

注意:我可以用 C# oo 风格做很长的事情,但想使用函数式方式

Mar*_*ann 5

这是一种使用方法Array.collect

let x =
    merchants
    |> Array.collect (fun m ->
        m.OtherItems
        |> Array.map (fun x -> { Id = m.Id; OtherItems = [|x|] }))
Run Code Online (Sandbox Code Playgroud)

你可以更容易理解我第一次介绍的一个扁平化单个商家的功能:

let flatten merchant = [|
    for x in merchant.OtherItems do
        yield { Id = merchant.Id; OtherItems = [|x|] } |]
Run Code Online (Sandbox Code Playgroud)

该函数的类型为Merchant -> Merchant [],因此它将单个商家转换为一组商家,每个商家一个OtherItems

通过该flatten函数,您可以使用标准的内置collect函数来扁平化商家数组:

let x' = merchants |> Array.collect flatten
Run Code Online (Sandbox Code Playgroud)

两个选项都会产生以下结果:

[|
    {Id = 1; OtherItems = [|1|];};
    {Id = 1; OtherItems = [|2|];};
    {Id = 2; OtherItems = [|1|];};
    {Id = 2; OtherItems = [|2|];}
|]
Run Code Online (Sandbox Code Playgroud)