配列の配列のデータセットがあります。例として
[[1,3],
[4,3],
[1,2],
[7,2]]
これをに変換したい
[(3,[1,4])
(2,[1,7])]
つまり、タプルの配列を作成します。最初のメンバーは元のインデックス1からのものであり、配列はインデックス1に基づいてグループ化された元のインデックス0のすべての値です。これは必須に解決できますが、実行したいと思います。よりFPのような方法で
配列の配列のデータセットがあります。例として
[[1,3],
[4,3],
[1,2],
[7,2]]
これをに変換したい
[(3,[1,4])
(2,[1,7])]
つまり、タプルの配列を作成します。最初のメンバーは元のインデックス1からのものであり、配列はインデックス1に基づいてグループ化された元のインデックス0のすべての値です。これは必須に解決できますが、実行したいと思います。よりFPのような方法で
Seq.groupBy
いくつかのマップと組み合わせて使用すると、望ましい結果が得られます
[[1;3];
[4;3];
[1;2];
[7;2]]
|> Seq.groupBy (fun (a::b) -> b)
|> Seq.map (fun (a,b) -> a,b|> Seq.toList)
|> Seq.map (fun (a,b) -> a,b|>List.map (fun (c::d) -> c ))
F# は静的に型付けされた関数型プログラミング言語であるため、最初に行うことは、入力を int のペアのリストなどの型付き表現に変換することです。
[ 1, 3
4, 3
1, 2
7, 2 ]
次に、Seq.groupBy
関数を使用してsnd
関数にパイプし、各ペアの 2 番目の要素にキーを設定できます。
|> Seq.groupBy snd
これにより、次の関数[3, [1, 3; 4, 3]; ...]
を使用して値だけを抽出する (つまり、キーを取り除く) 右辺にマップする必要があります。fst
|> Seq.map (fun (k, kvs) -> k, Seq.map fst kvs)
これにより、希望する答えが得られます: [(3, [1; 4]); (2, [1; 7])]
.
@John の回答に似ていますが、内部コレクションは少なくとも 2 つの要素を持つ配列であると仮定します。
[|[|1; 3|];
[|4; 3|];
[|1; 2|];
[|7; 2|]|]
|> Seq.map (fun arr -> arr.[0], arr.[1])
|> Seq.groupBy snd
|> Seq.map (fun (k, v) -> k, Seq.map fst v)
// val it : seq<int * seq<int>> = seq [(3, seq [1; 4]); (2, seq [1; 7])]
私の答えは上記の答えと本質的に異なるわけではありませんが、組み合わせロジックを少し使用しているため、(私には)より慣用的に見えます。また、いくつかの有効性チェックがあります。
Apply2
は本質的にS コンビネータです。
let data =
[[1;3];
[4;3];
[1;2];
[7;2]]
// Apply2 operator applies two functions to x
// and returns both results as a tuple
let (.&.) f g x = f x, g x
// A naive validator for sequences
let assert' predicate message xs =
if not <| Seq.forall predicate xs then
failwith message
xs
let aggregate data =
data
// validate the input
|> assert' (List.length >> (=) 2) "All elements must be of length of two"
// essentially, convert a 2-element list to a tuple
|> Seq.map (List.head .&. (List.tail >> List.head))
// group over the second element of a tuple
|> Seq.groupBy snd
// we no longer need the key element in a tuple, so remove it
|> Seq.map (fst .&. (snd >> Seq.map fst))
aggregate data |> printf "%A"