diff --git a/src/Data/List.purs b/src/Data/List.purs index 43d5ee3..d575c84 100644 --- a/src/Data/List.purs +++ b/src/Data/List.purs @@ -60,8 +60,10 @@ module Data.List , stripPrefix , slice , take + , takeEnd , takeWhile , drop + , dropEnd , dropWhile , span , group @@ -519,6 +521,13 @@ take = go Nil go acc _ Nil = reverse acc go acc n (x : xs) = go (x : acc) (n - 1) xs +-- | Take the specified number of elements from the end of a list. +-- | +-- | Running time: `O(2n - m)` where `n` is the number of elements in list +-- | and `m` is number of elements to take. +takeEnd :: forall a. Int -> List a -> List a +takeEnd n xs = drop (length xs - n) xs + -- | Take those elements from the front of a list which match a predicate. -- | -- | Running time (worst case): `O(n)` @@ -536,6 +545,13 @@ drop 0 xs = xs drop _ Nil = Nil drop n (x : xs) = drop (n - 1) xs +-- | Drop the specified number of elements from the end of a list. +-- | +-- | Running time: `O(2n - m)` where `n` is the number of elements in list +-- | and `m` is number of elements to drop. +dropEnd :: forall a. Int -> List a -> List a +dropEnd n xs = take (length xs - n) xs + -- | Drop those elements from the front of a list which match a predicate. -- | -- | Running time (worst case): `O(n)` diff --git a/test/Test/Data/List.purs b/test/Test/Data/List.purs index afab089..f476dc3 100644 --- a/test/Test/Data/List.purs +++ b/test/Test/Data/List.purs @@ -5,7 +5,7 @@ import Data.List.NonEmpty as NEL import Control.Monad.Eff (Eff) import Control.Monad.Eff.Console (CONSOLE, log) import Data.Foldable (foldMap, foldl) -import Data.List (List(..), (..), stripPrefix, Pattern(..), length, range, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, partition, span, dropWhile, drop, takeWhile, take, sortBy, sort, catMaybes, mapMaybe, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, unsnoc, init, tail, last, head, insertBy, insert, snoc, null, singleton, fromFoldable, transpose, mapWithIndex, (:)) +import Data.List (List(..), (..), stripPrefix, Pattern(..), length, range, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, partition, span, dropWhile, drop, dropEnd, takeWhile, take, takeEnd, sortBy, sort, catMaybes, mapMaybe, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, unsnoc, init, tail, last, head, insertBy, insert, snoc, null, singleton, fromFoldable, transpose, mapWithIndex, (:)) import Data.Maybe (Maybe(..), isNothing, fromJust) import Data.Monoid.Additive (Additive(..)) import Data.NonEmpty ((:|)) @@ -226,16 +226,26 @@ testList = do assert $ (take 2 (l [1, 2, 3])) == l [1, 2] assert $ (take 1 nil) == nil + log "takeEnd should keep the specified number of items from the end of an list, discarding the rest" + assert $ (takeEnd 1 (l [1, 2, 3])) == l [3] + assert $ (takeEnd 2 (l [1, 2, 3])) == l [2, 3] + assert $ (takeEnd 1 nil) == nil + log "takeWhile should keep all values that match a predicate from the front of an list" assert $ (takeWhile (_ /= 2) (l [1, 2, 3])) == l [1] assert $ (takeWhile (_ /= 3) (l [1, 2, 3])) == l [1, 2] assert $ (takeWhile (_ /= 1) nil) == nil - log "drop should remove the specified number of items from the front of an list" + log "dropE should remove the specified number of items from the front of an list" assert $ (drop 1 (l [1, 2, 3])) == l [2, 3] assert $ (drop 2 (l [1, 2, 3])) == l [3] assert $ (drop 1 nil) == nil + log "dropEnd should remove the specified number of items from the end of an list" + assert $ (dropEnd 1 (l [1, 2, 3])) == l [1, 2] + assert $ (dropEnd 2 (l [1, 2, 3])) == l [1] + assert $ (dropEnd 1 nil) == nil + log "dropWhile should remove all values that match a predicate from the front of an list" assert $ (dropWhile (_ /= 1) (l [1, 2, 3])) == l [1, 2, 3] assert $ (dropWhile (_ /= 2) (l [1, 2, 3])) == l [2, 3]