2016-10-28 6 views
0

Для строки str, как удалить каждый символ после n-го появления символа c?Удаление каждого символа после n-го появления символа в Haskell

Например, если str является "2016-10-20", как можно удалить все символы после 2-го вхождения символа -, уступая "2016-10"?

+1

Что должно произойти в вашем примере, если есть менее двух вхождений '-'? – Alec

ответ

3

В стандартной библиотеке нет удобной функции split, поэтому вам, по сути, нужно сворачивать самостоятельно. Один из подходов:

dropAfter :: Int -> Char -> String -> String 

dropAfter _ _ "" = "" 
dropAfter 0 d (x:xs) = "" 
dropAfter 1 d (x:xs) | x == d = "" 
dropAfter n d (x:xs) | x == d = x : dropAfter (n-1) d xs 
        | otherwise = x : dropAfter n d xs 

split пакет, однако, не предусматривает splitOn :: Eq a => [a] -> [a] -> [[a]]:

import Data.List.Split (splitOn) 
import Data.List (intercalate) 
dropAfter n d = intercalate [d] . take n . splitOn [d] 
3

складка Fiend удары снова.

dropAfter :: Int -> (a -> Bool) -> [a] -> [a] 
dropAfter n _ _ | n < 1 = [] 
dropAfter n f xs = foldr go (`seq` []) xs n where 
    go x r !k 
    | f x = if k == 1 then [] else x : r (k - 1) 
    | otherwise = x : r k 
+0

why '(\' seq \ '[])' а не 'const []'? – rampion

+1

@rampion, это моя привычка помогать в анализе строгости (и, следовательно, распаковывать), когда смогу. Это 'seq' гарантирует, что всегда требуется значение обновленного аккумулятора. В этом случае это может и не понадобиться, но я видел похожие формы с 'const' смешно, когда они заканчиваются в достаточно сложном контексте. – dfeuer

1

В качестве альтернативы, вы можете использовать это как трамплин, чтобы начать использовать парсер:

λ import Text.Parsec 
λ runParser (many (noneOf "-") `sepBy` char '-')() "example from question" "2016-01-43" 
Right ["2016","01","43"] 
λ import Data.List 
λ intercalate "-" . take 2 <$> it 
Right "2016-01" 

Хорошей вещь о том, чтобы переключатель в настоящее время является то, что, как вы узнаете больше о вашем входе (и что он может и не может выглядеть), довольно легко обновить парсер, чтобы он соответствовал, где использование пользовательской функции может стать реальным hinky real fast.

Смежные вопросы