2012-04-21 30 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