问题
How can you remove every nth element of a string?
I'm guessing you would use the drop
function in some kind of way.
Like this drops the first n, how can you change this so only drops the nth, and then the nth after that, and so on, rather than all?
dropthem n xs = drop n xs
回答1:
remove_every_nth :: Int -> [a] -> [a]
remove_every_nth n = foldr step [] . zip [1..]
where step (i,x) acc = if (i `mod` n) == 0 then acc else x:acc
Here's what the function does:
zip [1..]
is used to index all items in the list, so e.g. zip [1..] "foo"
becomes [(1,'f'), (2,'o'), (3,'o')]
.
The indexed list is then processed with a right fold which accumulates every element whose index is not divisible by n
.
Here's a slightly longer version that does essentially the same thing, but avoids the extra memory allocations from zip [1..]
and doesn't need to calculate modulus.
remove_every_nth :: Int -> [a] -> [a]
remove_every_nth = recur 1
where recur _ _ [] = []
recur i n (x:xs) = if i == n
then recur 1 n xs
else x:recur (i+1) n xs
回答2:
Simple. Take (n-1) elements, then skip 1, rinse and repeat.
dropEvery _ [] = []
dropEvery n xs = take (n-1) xs ++ dropEvery n (drop n xs)
Or in showS style for efficiency's sake
dropEvery n xs = dropEvery' n xs $ []
where dropEvery' n [] = id
dropEvery' n xs = (take (n-1) xs ++) . dropEvery n (drop n xs)
回答3:
-- groups is a pretty useful function on its own!
groups :: Int -> [a] -> [[a]]
groups n = map (take n) . takeWhile (not . null) . iterate (drop n)
removeEveryNth :: Int -> [a] -> [a]
removeEveryNth n = concatMap (take (n-1)) . groups n
回答4:
Try to combine take
and drop
to achieve this.
take 3 "hello world" = "hel"
drop 4 "hello world" = "o world"
回答5:
I like the following solution:
del_every_nth :: Int -> [a] -> [a]
del_every_nth n = concat . map init . group n
You just have to define a function group
which groups a list in portions of length n. But that's quite easy:
group :: Int -> [a] -> [[a]]
group n [] = []
group n xs = take n xs : group n (drop n xs)
来源:https://stackoverflow.com/questions/5289010/remove-every-nth-element-from-string