2017-03-06 15 views
1

リスト内のすべての要素のコピーを作成できるものを書きたいと思います。私は、リストの2F# - リスト内の要素のコピーを作成するには?

[1; 2; 3; 4] 

を望んでいたのであれば、それは

[1; 1; 2; 2; 3; 3; 4; 4] 

は、だから私は

カウントは私が欲しい部数です
let rec dupeElem row count = 
    match row with 
    | [] -> [] 
    | hd::tl -> (makeCopy hd count) @ dupeElem tl count 

で再帰関数を書く上で計画していたとなります。この関数は、リスト内の各head要素を取得し、コピー関数に送信してリストに挿入するためのコピーを作成します。それでmakeCopyは次のようになります:

let makeCopy elem Count = 
    match Count with 
    | 0 -> [] 
    | 1 -> elem 
    | 2 -> elem :: elem 
    |.... 

しかし、私はdupeElemに返されるときにエラーが発生します。私は賢明なアイデアではないが、それがうまくいくかどうかをテストすることでした。私はそれを動作させるために何を修正/改良すればよいでしょうか?

答えて

3

makeCopy0ケースのリストを返しますが、1の場合は単一のエレメントを返しています。右手側はリストではありませんので、場合2については

| 1 -> [elem] 

は、::のご使用は無効であるが、それは単一の要素である:以下に1のためのケースを変更すると、コンパイル時のエラーを修正する必要があります。以下のいずれかでそれを置き換えることを検討:

| 2 -> elem :: [elem] 

それとも...

| 2 -> [ elem; elem ] 
+0

「リストリストを期待していますが、「intリスト」を取得しているというエラーが表示されています –

+0

私の更新された回答を参照してください –

+0

ありがとうございました! –

7

ただ、非再帰的なソリューションのために:

let xs = [1; 2; 3; 4; 5] 
xs |> List.collect (fun x -> List.replicate 3 x) 
//val it : int list = [1; 1; 1; 2; 2; 2; 3; 3; 3; 4; 4; 4; 5; 5; 5] 
+0

ありがとう!この方法を知らなかった。 –

2

相互に再帰的な方法:

let rec dupl n = function 
    | [] -> [] 
    | h::t -> cons h (dupl n t) n 
and cons h t = function 
    | 0 -> t 
    | n -> cons h (h::t) (n-1) 
0

0による回答はきれいで簡単です。あなただけ複製したくない場合は、より一般性のために、あなたは、関数f、gおよびhを定義し、次の行うことができます:あなたはちょうどあなたが可能性複製したいあなたの特定のケースについては

let xs = [1; 2; 3; 4] 
let f = id // No need for type annotation, given the definitions of g and h 
let g x = x * x 
let h x = x * x * x 
(List.zip3 xs xs xs) |> List.map (fun (a, b, c) -> [f a; g b; h c]) |> List.concat 

をdo

let f = id<int> // The type annotation is necessary 

と同様に、gとhの場合、またはfを3つの場合すべて使用します。もちろん、この場合には、s952163によって提案された解決策が非常に好ましい。

関連する問題