将数组数组减少为单个数组,并在f#中展平

时间:2015-10-04 12:57:42

标签: 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|]

我想要做到以下几点,我该怎么做?

Id = 1 OtherItems 1  
Id = 1 OtherItems 2 
Id = 2 OtherItems 1  
Id = 2 OtherItems 2

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

let x = 
    merchants
     |> Array.map(fun merchant -> merchant, merchant.OtherItems)

注意:我可以在c#oo风格中做很多事情,但想要使用功能方式

2 个答案:

答案 0 :(得分:4)

这是使用Array.collect的方式:

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

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

let flatten merchant = [|
    for x in merchant.OtherItems do
        yield { Id = merchant.Id; OtherItems = [|x|] } |]

此功能的类型为Merchant -> Merchant [],因此它会将单个商家转变为商家数组,每个商家一个OtherItems

使用flatten函数,您可以使用标准的内置collect函数来展平商家阵列:

let x' = merchants |> Array.collect flatten

这两个选项都会产生这样的结果:

[|
    {Id = 1; OtherItems = [|1|];};
    {Id = 1; OtherItems = [|2|];};
    {Id = 2; OtherItems = [|1|];};
    {Id = 2; OtherItems = [|2|];}
|]

答案 1 :(得分:3)

使用序列生成:

let mySequence =
    seq {
        for merchant in merchants do
            for otherItem in merchant.OtherItems do
                yield {Id=merchant.Id; OtherItems=[|otherItem|]}
    }

或数组生成

let myArray =
    [|
        for merchant in merchants do
            for otherItem in merchant.OtherItems do
                yield {Id=merchant.Id; OtherItems= [|otherItem|]}
    |]