Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drop until the last occurence of a pattern in Haskell

Tags:

haskell

dropWhile asks for a predicate and removes an element from a list one by one until predicate is false for the first time, then it just returns what's left. For example you could remove elements from a list of strings until you find a string that starts with a slash:

> dropWhile (not . isPrefixOf "/") ["a", "b", "/c", "d"]
["/c","d"]

But what if you want to continuously delete elements until you match a pattern for the last time? For example, Python's os.path.join accepts arbitrary number of string parameters. If any parameter starts with a slash, all previous are ignored, and the remaining are joined with a separator:

>>> os.path.join("a", "/b", "c", "/d", "e")
'/d/e'

How do I continuously drop elements from a list until some condition is met for the last time?

like image 473
Mirzhan Irkegulov Avatar asked Aug 02 '14 21:08

Mirzhan Irkegulov


1 Answers

groupBy allows to group elements of a list based on a predicate that somehow compares each two near elements. Every time predicate fails, the new group is started. So to group elements by each occurrence of a slash prefix, every time the string starts with a slash, we should start a new group, therefore the predicate must fail:

> groupBy (\x y -> not $ isPrefixOf "/" y) ["a", "/b", "c", "/d", "e"]
[["a"],["/b","c"],["/d","e"]]

The general version, therefore, must look like this:

dropUntilLast :: (a -> Bool) -> [a] -> [a]
dropUntilLast f = last . groupBy (\x y -> not $ f y)
like image 64
Mirzhan Irkegulov Avatar answered Oct 29 '22 14:10

Mirzhan Irkegulov