2012-04-21 31 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 2012-04-21 08:21:00

+1

請注意,如果您發現自己刪除索引處的元素(遠離列表的前面)很多,您可能需要重新考慮您選擇的數據結構或算法。 – gspr 2015-12-05 09:58:15

回答

9

splitAt來定義它會簡單得多,它在給定索引之前分割列表。然後,您只需從第二部分中移除第一個元素並將它們粘合在一起即可。

+2

我已經這樣做了:) 但我認爲有內置函數 – malhobayyeb 2012-04-21 04:57:47

+0

@ MIH1406:在特定位置刪除列表元素在Haskell中不是很習慣,這就是爲什麼沒有內建函數功能。 – Vitus 2012-04-21 10:28:54

3

reverse如果你可以在haskell中,可以避免串聯。它看起來會對我有用,但我對此並不完全確定。

但是,要回答「真實」的問題:是的,還有另一種(更簡單)的方法。基本上,在使用haskell時,你應該像往常一樣查找:遞歸。看看你能否做出這個函數的遞歸版本。

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

你能看到一種方法來保存每一步的比較嗎? – dfeuer 2015-12-05 20:39:33

+0

你能解釋一下你想在這裏做什麼嗎? – 2015-12-05 21:38:31

+4

感謝您發佈這個問題的答案! Stack Overflow不鼓勵使用代碼解答,因爲原始海報(或未來的讀者)很難理解其背後的邏輯。請編輯你的問題,幷包括你的代碼的解釋,以便其他人可以從你的答案中受益。謝謝! – 2015-12-05 23:10:24

0

這裏是我的解決方案:

removeAt xs n  | null xs = [] 
removeAt (x:xs) n | n == 0 = removeAt xs (n-1) 
        | otherwise = x : removeAt xs (n-1) 
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 

呼叫 '刪除' 以數字和一個列表作爲參數的功能。你會得到一個沒有這個數字作爲輸出的列表。 在上面的代碼中,remove_temp函數返回列表中存在編號的索引。然後刪除功能在數字和數字之後取出列表使用內置的「取」和「放」功能的前奏。最後,這兩個列表的連接完成,它給出一個沒有輸入數字的列表。

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) 

我是一個總的哈斯克爾小白,所以如果這是錯誤的,請解釋原因。

我通過閱讀splitAt的定義想到了這一點。根據Hoogle的說法,「這相當於(拿n xs,放n xs)」。這讓我覺得,如果我們只是不加一個額外的數字,那麼如果我們重新加入,那麼它基本上會被刪除。

這裏是我的文章引用Hoogle link

下面是運行它的測試:

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

難道你不能只是'(取(n-1)xs)++(drop n xs)'而不是定義一個元組來存儲兩個不同的值,然後將它們都拉出來? – Matthias 2018-02-26 22:43:35

+0

我想你可以 – liamnp 2018-03-01 21:41:16