簡體   English   中英

F#數組-要輸出Seq的Seq的輸入數組

[英]F# Arrays - Input Arrays To Output Seq of Seqs

我有三個數組,當前兩個數組對齊時-[|(“ C”,“ No”),(“ C”,“ Yes”); ... |]-並且由第三個數組過濾應生成一個“ seq of seqs”-[...; seq [(“ C”,(“ No”,1),(“ Yes”,1)]; ...] ;:

module SOQN = 

   open System

   let first    = [| "C"; "D"; "C"; "E"; "B"; "A"; "A"; "E"; "A"; "B"; "A"; "D"; "B"; "E" |]
   let second   = [| "No"; "No"; "Yes"; "Yes"; "Yes"; "No"; "Yes"; "No"; "Yes"; "Yes"; "Yes"; "Yes"; "Yes"; "No" |]
   let fltr     = [| "No"; "Yes" |]

   let filterProduct (first:string[]) (second:string[]) (fltr:string) = 
      Array.zip first second
      |> Array.filter (fun (_, s) ->
         Seq.forall (fun c -> s.Contains (string c)) fltr)
      |> Array.map fst
      |> Array.reduce (fun acc item -> acc + ", " + item)

   let third = 
      [for i in [0..fltr.Length - 1] do
         yield (filterProduct first second fltr.[i])]
      |> List.toArray

   printfn "third: %A" third

  // Expected Result: third: [seq [("A", ("No", 1), ("Yes", 3)]; 
  //                          seq [("B", ("No", 0), ("Yes", 3)]; 
  //                          seq [("C", ("No", 1), ("Yes", 1)]; 
  //                          seq [("C", ("No", 1), ("Yes", 1)];
  //                          seq [("C", ("No", 2), ("Yes", 1)]]

  // Actual Result:   third: [|"C, D, A, E, E"; "C, E, B, A, A, B, A, D, B"|]

如何產生預期的結果?

好吧,基於所包含代碼中的注釋,您期望看到Seq <Seq <... >>數據,其中...是關鍵點。 不幸的是,您將無法通過這種方式執行此操作,因為如果您檢查內部序列的元素,則會使用以下命令:(“ A”,(“ No”,1),(“ Yes”,3)。首先,缺少結束括號(沒什么大不了的),其次,內部seq具有混合類型,第一個元素是字符串,第二個和第三個元素是string和int的元組。

對預期結果進行一些修改,您可以通過以下方式實現類似的目的:

let first    = [| "C"; "D"; "C"; "E"; "B"; "A"; "A"; "E"; "A"; "B"; "A"; "D"; "B"; "E" |]
let second   = [| "No"; "No"; "Yes"; "Yes"; "Yes"; "No"; "Yes"; "No"; "Yes"; "Yes"; "Yes"; "Yes"; "Yes"; "No" |]
let fltr     = [| "No"; "Yes" |]

let filterProduct (first:string[]) (second:string[]) (fltrs:string []) = 
    Array.zip first second
    |> Array.groupBy fst
    |> Array.map (fun (k, values) ->
        k,
            fltrs
            |> Array.map (fun fltr ->
                let c = values |> Array.map snd |> Array.filter (fun x -> x = fltr) |> Array.length
                fltr, c
            )
    )
    |> Array.sortBy (fun (k, v) -> k)

let third = 
    filterProduct first second fltr

printfn "third: %A" third

這樣, third具有以下格式:

seq<string * seq<string * int>>

這與我想要的非常接近!

module SOANS = 

  open System

  let first        = [| "C"; "D"; "C"; "E"; "B"; "A"; "A"; "E"; "A"; "B"; "A"; "D"; "B"; "E" |]
  let firstFilter  = [| "A"; "B"; "C"; "D"; "E" |]
  let second       = [| "No"; "No"; "Yes"; "Yes"; "Yes"; "No"; "Yes"; "No"; "Yes"; "Yes"; "Yes"; "Yes"; "Yes"; "No" |]
  let secondFilter = [| "No"; "Yes" |]

  let filterProduct (first:string[]) (second:string[]) (secondFilter:string) = 
     Array.zip first second
     |> Array.filter (fun (_, s) ->
        Seq.forall (fun c -> s.Contains (string c)) secondFilter)
     |> Array.map fst
     |> Array.toSeq

  let third = 
     [for i in [0..firstFilter.Length - 1] do
        yield (filterProduct second first firstFilter.[i])]
     |> List.countBy id
     |> List.toSeq

  let fourth = 
     third
     |> Seq.map (fun (s, _) -> s |> (Seq.countBy id) |> Seq.sort)

  printfn ""
  printfn "fourth:"
  fourth |> Seq.iter (fun (c) -> (printf "%A; " c))

  // Expected Result: fourth: [seq [("A", ("No", 1), ("Yes", 3)]; 
  //                           seq [("B", ("No", 0), ("Yes", 3)]; 
  //                           seq [("C", ("No", 1), ("Yes", 1)]; 
  //                           seq [("C", ("No", 1), ("Yes", 1)];
  //                           seq [("C", ("No", 2), ("Yes", 1)]]
  // Actual Result:   fourth: seq [("No", 1); ("Yes", 3)]; 
  //                          seq [("No", 0); ("Yes", 3)]; 
  //                          seq [("No", 1); ("Yes", 1)]; 
  //                          seq [("No", 1); ("Yes", 1)]; 
  //                          seq [("No", 2); ("Yes", 1)];

我不確定您是否希望看到零是或否計數。 如果沒有,下面的代碼可能會有所幫助。

namespace FSharpBasics

module Classifier =

    let private first    = 
        [| "C"; "D"; "C"; "E"; "B"; "A"; "A"; "E";
        "A"; "B"; "A"; "D"; "B"; "E" |]
    let private second   = 
        [| "No"; "No"; "Yes"; "Yes"; "Yes"; "No"; "Yes"; "No";
        "Yes"; "Yes"; "Yes"; "Yes"; "Yes"; "No" |]
    //let private fltr     = 
    //    [| "No"; "Yes" |]

    (* operations *)
    let pair =
        Array.zip

    let classifier =
        let intermediate =
            pair first second

        let result = 
            intermediate
            |> Seq.groupBy (fun (first, _) -> first)
            |> Seq.map (fun (first, grouping) -> 
                (first, grouping 
                        |> Seq.groupBy (fun (_, second) -> second)
                        |> Seq.map (fun (second, grouping) ->
                            (second, grouping
                                     |> Seq.length))))
        seq {
            for x in result do yield x
        }

    [<EntryPoint>]
    let main argv =
        classifier |> Seq.iter (printfn "%A")
        System.Console.ReadKey() |> ignore
        0

(* ---Result----

("C", seq [("No", 1); ("Yes", 1)])
("D", seq [("No", 1); ("Yes", 1)])
("E", seq [("Yes", 1); ("No", 2)])
("B", seq [("Yes", 3)])
("A", seq [("No", 1); ("Yes", 3)])

---- ----*)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM