2009-06-24 28 views
6

我正在通過Learn You a Haskell閱讀,並且我試圖將列表中的元素移動到頭部。我想出了我認爲是天真的方式,我很好奇,如果有人能告訴我經驗豐富的Haskell程序員會做什麼。如何在Haskell中移動列表中的元素?

在這個例子中,我有一個整數列表,我想將元素'4',它將索引'3',到列表的頭部。

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 

刪除給定元素的第一次出現,所以如果有可能刪除錯誤的元素重複... – sth 2009-06-24 23:25:44

回答

15

我會做這種方式:

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

splitAt在給定的位置分割的列表,它返回由分裂(這裏hsts)創建的兩個部分。應該移動到前面的元素現在在ts的開頭。 head ts只返回ts的這第一個元素,tail ts返回所有內容但是表示第一個元素。函數的結果只是這些部分以正確的順序組合在一起:hstail ts級聯,並由元素head ts作爲前綴。

+3

toHead n l = let(xs,y:ys)= splitAt n l in y:xs ++ ys – Stephan202 2009-06-24 23:24:43

+0

......請問您能否描述一下請理解代碼? – shahkalpesh 2009-06-24 23:31:01

0

什麼是共同發病?
幾天前我在讀相同的東西。再看一遍&寫下如下。

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

兩個問題:首先,重複的元素被刪除。其次(較少的問題),不等於運算符是(/ =),而不是((a == b)== False)。 – 2009-06-24 23:25:14

+0

好抓。正如你所看到的,我是一個初學者。謝謝糾正:) – shahkalpesh 2009-06-24 23:28:46

11

有經驗的Haskellers很少使用列表索引。我會用突破來避免重複遍歷(假設你想匹配的元素「4」,而不是指數「3」):

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

如:

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] 

我們可以做同樣的通過 '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

是的,它與元素4不匹配索引'3'。對不起,混淆 – afrosteve 2009-06-25 04:32:38

3

還有

toHead n l = l !! n : take n l ++ drop (n+1) l 

這可能比使用splitAt稍微容易一些。

8

對某事的解決方案小的修改:使用模式的匹配,而不是headňtail

相關問題