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?
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With