2017-10-16 18 views
2

ファンキーなタイトルを(* bのリスト)に戻るには、(* b)のリストを考えると、私は次のように問題を抱えている:は、おそらくリスト

タイプ(a * b) listのリストを考えると、私が欲しいですタイプ(a * b list) listの新しいリストを作成します。例:

リストlet testList = [(1,"c");(2,"a");(1,"b")]が指定されている場合、私の関数は[(1, ["c";"b"]; (2, ["a"])]を返します。

私は以下を持っていますが、私は継続する方法について少しこだわっている:

let rec toRel xs = 
    match xs with 
    | (a,b)::rest -> (a,[b])::toRel rest 
    | _   -> [] 
+1

あなたは非常にエレガントなソリューションである '' List.groupBy'' – Gustavo

答えて

8

あなたは組み込み関数List.groupByを使用し、冗長化キー削除するためにマップすることができます:

testList |> List.groupBy fst |> List.map (fun (k,v) -> (k, List.map snd v)) 

// val it : (int * string list) list = [(1, ["c"; "b"]); (2, ["a"])] 
をあなたは試合を続行するかどう

は、そうしないと、このような何かを行うことができます。

let toRel x = 
    let rec loop acc xs = 
     match xs with 
     | (k, b) :: rest -> 
      let acc = 
       match Map.tryFind k acc with 
       | Some v -> Map.add k (b::v) acc 
       | None -> Map.add k [b] acc 
      loop acc rest 
     | _    -> acc 
    loop Map.empty x |> Map.toList 

それともあなたはそれを書くことができOption.toListを使用して:

let toRel x = 
    let rec loop acc xs = 
     match xs with 
     | (k, b) :: rest -> 
      let acc = 
       let lst = Map.tryFind k acc |> Option.toList |> List.concat 
       Map.add k (b::lst) acc 
      loop acc rest 
     | _    -> acc 
    loop Map.empty x |> Map.toList 
+0

を使用することができます。あなたは高次関数なしでそれを行うための提案がありますか? – Khaine775

+1

私はあなたがやろうとしていたと思うマッチの例を追加しました。しかし、イテレータを使うこともできます。 – Gustavo

関連する問題