2015-10-04 16 views
2

壓扁如果我有以下減少數組的數組到一個單一的陣列,以在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#中面向對象的風格很長的路要走,但希望使用功能性的方式

回答

3

下面是使用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|];} 
|] 
+0

標誌,這個工作對於我在腳本文件,但是當我把我的fs文件我得到「唱片公司」Id「沒有定義」 – Noel

+0

@Nelel我怎麼repro呢? –

+0

我會試着展示這個.. – Noel

2

使用序列生成:

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|]} 
    |]