I have a Scala app with a list of items with checkboxes so the user select some, and click a button to shift them one position up (left). I decided to write a function to sh
I don't know enough to write it in Scala, but this problem is tailor-made for the list functions takeWhile
and dropWhile
. The idea is that you split the list of items into three parts:
Left part, computed with takeWhile
, contains leftmost elements not satisfying the predicate.
Middle part is the group of elements you want to shift left, computed by dropping the left elements and then takeWhile
the remainder.
Right part is everything left over; dropWhile
the middle elements.
Here it is in Haskell:
-- take first group of elements satisfying p and shift left one
shift :: (a -> Bool) -> [a] -> [a]
shift p l = case reverse left of
[] -> l
(a:as) -> reverse as ++ middle ++ a : shift p right
where left = takeWhile (not . p) l -- could be done with List.break
notLeft = dropWhile (not . p) l
middle = takeWhile p notLeft -- could be done with List.span
right = dropWhile p notLeft
And here's a single unit test:
*Shiftup> shift (>9) [1, 2, 3, 44, 55, 6, 7, 8]
[1,2,44,55,3,6,7,8]
Haskell programmers might use List.break
or List.span
to combine calls to takeWhile
and dropWhile
, but I'm not sure if Scala has these things. Besides, takeWhile
and dropWhile
are nice meaningful names, whereas I at least find break
and span
less perspicuous.
EDIT: fixed recursive call to do shift p right
instead of right
to shift up all groups.