3

The function I'm trying to write should remove the element at the given index from the given list of any type.

Here is what I have already done:

           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

Is this correct? Could anyone suggest another approach?

2
  • 2
    consider drop instead of reverse - take - reverse Commented Apr 21, 2012 at 8:21
  • 1
    Note that if you find yourself removing an element at an index (far from the front of the list) a lot, you might want to reconsider your choice of data structure, or your algorithm. Commented Dec 5, 2015 at 9:58

6 Answers 6

9

It's much simpler to define it in terms of splitAt, which splits a list before a given index. Then, you just need to remove the first element from the second part and glue them back together.

Sign up to request clarification or add additional context in comments.

2 Comments

I already did that, too :) But I thought there is built-in function
@MIH1406: Removing an element of a list at a specific location is not very idiomatic in Haskell, that's why there isn't a build-in function.
3

reverse and concatenation are things to avoid if you can in haskell. It looks like it would work to me, but I am not entirely sure about that.

However, to answer the "real" question: Yes there is another (easier) way. Basically, you should look in the same direction as you always do when working in haskell: recursion. See if you can make a recursive version of this function.

Comments

2

Super easy(I think):

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

I'm a total Haskell noob, so if this is wrong, please explain why.

I figured this out by reading the definition of splitAt. According to Hoogle, "It is equivalent to (take n xs, drop n xs)". This made me think that if we just didn't take one extra number, then it would be basically removed if we rejoined it.

Here is the article I referenced Hoogle link

Here's a test of it running:

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

2 Comments

Couldn't you just do (take (n-1) xs) ++ (drop n xs) instead of defining a tuple to store two different values and then pulling them both out?
I guess you could
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"

3 Comments

Can you see a way to save one comparison per step?
Can you explain what you're trying to do here a but more please?
Thank you for posting an answer to this question! Code-only answers are discouraged on Stack Overflow, because it can be difficult for the original poster (or future readers) to understand the logic behind them. Please, edit your question and include an explanation of your code so that others can benefit from your answer. Thanks!
0

Here is my solution:

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

Comments

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

Call 'remove' function with a number and a list as parameters. And you'll get a list without that number as output. In the above code, remove_temp function returns the index at which the number is present in the list. Then remove function takes out the list before the number and after the number using inbuilt 'take' and 'drop' function of the prelude. And finally, concatenation of these two lists is done which gives a list without the input number.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.