2012-04-21 54 views
2

私が書いようとしている関数は、与えられたインデックスの要素を与えられた型のリストから削除するべきです。ここでHaskellのリストから要素を削除するには?

は、私がすでにやっていることです:

  delAtIdx :: [x] -> Int -> [x] 

      delAtIdx x y = let g = take y x 
          in let h = reverse x 
          in let b = take (((length x) - y) - 1) h 
          in let j = g ++ (reverse b) 
          in j 

は、この正しいですか?誰もが別のアプローチを提案できますか?

+2

はdrop'代わりに 'reverse'の'考える - 'take' - ' reverse' – newacct

+1

注場合は、その索引の要素をリストの先頭からずっと削除すると、データ構造の選択やアルゴリズムの見直しが必要になることがあります。 – gspr

答えて

9

splitAtで定義する方がずっと簡単です。これは、指定されたインデックスの前にリストを分割します。次に、最初の要素を2番目の部分から削除し、それらを再び接着する必要があります。

removeAt xs n  | null xs = [] 
removeAt (x:xs) n | n == 0 = removeAt xs (n-1) 
        | otherwise = x : removeAt xs (n-1) 
+2

私はすでにそれもしています:) しかし、私は組み込み関数があると思いました – malhobayyeb

+0

@ MIH1406:特定の場所でリストの要素を削除することは、Haskellではそれほど慣習的ではありません。関数。 – Vitus

3

reverseあなたがhaskellでできる場合、避けるべきことがあります。それは私にはうまくいくように見えますが、私はそれについて完全にはわかりません。

しかし、「本当の」質問に答えるには:はい、別の(簡単な)方法があります。基本的には、iskell:recursionで作業しているときといつも同じ方向に見てください。この関数の再帰的なバージョンを作ることができるかどうかを見てください。

0
deleteAt :: Int -> [a] -> [a] 
deleteAt 0 (x:xs) = xs 
deleteAt n (x:xs) | n >= 0 = x : (deleteAt (n-1) xs) 
deleteAt _ _ = error "index out of range" 
+0

ステップごとに1つの比較を保存する方法がありますか? – dfeuer

+0

ここでは何をしようとしているのか説明できますか? –

+4

この質問への回答をありがとう!元のポスター(または今後の読者)がそれらの背後にあるロジックを理解することは難しいため、スタックオーバーフローではコードのみの回答は推奨されません。あなたの質問を編集し、他の人があなたの答えから恩恵を受けるようにあなたのコードの説明を入れてください。ありがとう! –

0

は、ここに私のソリューションです。そしてその番号のないリストを出力として取得します。 上記のコードでは、remove_temp関数は、番号がリストに存在するインデックスを返します。その後、機能を削除するには、番号の前にリストを取り出し、プルードの組み込みの「テイク」と「ドロップ」機能を使用します。そして最後に、これら2つのリストの連結が行われ、入力番号のないリストが得られます。

0
remove_temp num l i | elem num (take i l) == True = i 
        | otherwise = remove_temp num l (i+1) 

remove num l = (take (index-1) l) ++ (drop index l) 
       where index = remove_temp num l 1 

コール '削除' 数をパラメータとしてリストを持つ関数:

2

超簡単(と思う):

removeIndex [] 0 = error "Cannot remove from empty array" 
removeIndex xs n = fst notGlued ++ snd notGlued 
    where notGlued = (take (n-1) xs, drop n xs) 

私は総Haskellのnoobのだ、そう、これは間違っている場合は、理由を説明してください。

私はsplitAtの定義を読んでこれを理解しました。 Hoogleによれば、「(n×x、n×xを取る)と同等です」これは、もし私たちが1つの余分な数字を取っていないのであれば、私たちがそれに再び参加すれば基本的に削除されると思っていました。

は、ここで私はHoogle link

を参照記事は、ここで実行していることのテストですされています

*Main> removeIndex [0..10] 4 
[0,1,2,4,5,6,7,8,9,10] 
+0

2つの異なる値を格納するタプルを定義するのではなく、 '((n-1)xs)++(drop n xs)'を実行して両方を引き出すことができませんでしたか? – Matthias

+0

私はあなたができると思います – liamnp

関連する問題