2009-06-24 12 views
6

私はLearn You a Haskellまで読んでいて、リストの中の要素を頭に動かそうとしているところに達しました。経験を積んだHaskellのプログラマが代わりにやることを誰かが私に見せることができれば、私は好奇心が強いのです。Haskellのリストの要素を移動するには?

この例では、整数のリストがあり、インデックス '3'の要素 '4'をリストの先頭に移動したいとします。

let nums = [1, 2, 3, 4, 5] 
(nums !! 3) : delete (nums !! 3) nums 

[4,1,2,3,5]を返します。

あなたはどう思いますか?

+3

は、「削除」のパターンマッチングを使用して

toHead n xs = x : pre ++ post where (pre, x:post) = splitAt n xs 

が与えられた要素の最初の発生を削除し、そうある場合、それは間違った要素を削除するかもしれませんduplicates ... – sth

答えて

15

私は、このようにそれを行うだろう:

move n as = head ts : (hs ++ tail ts) 
    where (hs, ts) = splitAt n as 

splitAtはそれが分割(ここhsts)によって作成される2つの部品を返し、所定の位置にリストを分割します。正面に移動する必要がある要素は、今度はtsの先頭にあります。 head tsは、tsの最初の要素を返します。tail tsは、すべてではなく、最初の要素であるを返します。関数の結果は、hstail tsと連結され、要素の前にhead tsが付加された、これらの部分が正しい順序で結合されたものになります。

+3

toHead n = let(xs、y:ys)= splitAt y in:xs ++ ys – Stephan202

+0

sth:コードを理解してください。 – shahkalpesh

0

どのような同時発生率ですか?
私は数日前に同じことを読んでいました。再度それを見て&は次のように書いています。

nums !! 3 : [x | x <- nums, (x == (num !! 3)) == False] 
+0

2つの問題:まず、重複した要素が削除されます。二番目(問題のほうが少ない)、not equal演算子は(a == b)== Falseではなく、(==)です。 –

+0

良いキャッチ。ご覧のとおり、私は初心者です。訂正していただきありがとうございます。 – shahkalpesh

11

リスト索引付けをほとんど使用していない経験のあるハスケラー。私は繰り返しトラバーサルを避けるためにブレークを使用したい(あなたが要素に一致させたいと仮定すると「4」ではなく、インデックスを「3」):私たちは同じことを行うことができます

Prelude Data.List> case break (== 4) [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs 
[4,1,2,3,5] 

case break (== 4) [1, 2, 3, 4, 5] of 
    (a,x:xs) -> x:a ++ xs 
    (a,xs) -> a ++ xs 

のように'splitAt' を介してインデックスを:

Prelude Data.List> case splitAt 3 [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs 
[4,1,2,3,5] 
+0

はい、インデックス '3'にない要素4で一致しています。混乱のため申し訳ありません – afrosteve

3

toHead n l = l !! n : take n l ++ drop (n+1) l 
もあります

これは、splitAtを使用した場合よりも少し簡単です。

STHのソリューションに
+0

これはsplitAtバージョンよりも遅いですか? – yairchu

+0

オプティマイザが処理を完了した後は明確になりません。 ghc -Oで実行してみてください! –

+0

これは2がリストを通過するでしょうか? – Daniel

8

小さな修正:代わりにhead nはtail

+1

これは解決策を理解するのが最も簡単だと思います。パターンマッチングで素敵なタッチ! – Michael

関連する問題