Skip to content

Commit 065ad63

Browse files
committed
Implemented groupBy and span in ffi. Added group'.
1 parent a537bee commit 065ad63

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545

4646
group :: forall a. (Eq a) => [a] -> [[a]]
4747

48+
group' :: forall a. (Ord a) => [a] -> [[a]]
49+
4850
groupBy :: forall a. (a -> a -> Prim.Boolean) -> [a] -> [[a]]
4951

5052
head :: forall a. [a] -> Maybe a

src/Data/Array.purs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module Data.Array
3131
, sort
3232
, sortBy
3333
, group
34+
, group'
3435
, groupBy
3536
, span
3637
) where
@@ -289,15 +290,48 @@ foreign import sortJS
289290
group :: forall a. (Eq a) => [a] -> [[a]]
290291
group xs = groupBy (==) xs
291292

292-
groupBy :: forall a. (a -> a -> Boolean) -> [a] -> [[a]]
293-
groupBy _ [] = []
294-
groupBy eq (x:xs) = case span (eq x) xs of
295-
{init = ys, rest = zs} -> (x:ys) : groupBy eq zs
293+
-- | Performs a sorting first.
294+
group' :: forall a. (Ord a) => [a] -> [[a]]
295+
group' = group <<< sort
296296

297-
span :: forall a. (a -> Boolean) -> [a] -> { init :: [a], rest :: [a] }
298-
span p (x:xs') | p x = case span p xs' of
299-
{init = ys, rest = zs} -> {init: (x:ys), rest: zs}
300-
span _ xs = {init: [], rest: xs}
297+
foreign import groupBy
298+
"function groupBy (eq) {\
299+
\ return function (arr) {\
300+
\ if (arr.length == 0) {\
301+
\ return [];\
302+
\ } else {\
303+
\ var res = [];\
304+
\ var spanned = {init: [], rest: arr.slice()};\
305+
\ while (true) {\
306+
\ var x = spanned.rest[0];\
307+
\ var xs = spanned.rest.slice(1);\
308+
\ spanned = span(eq(x))(xs);\
309+
\ spanned.init.unshift(x);\
310+
\ res.push(spanned.init);\
311+
\ if (spanned.rest.length == 0) {\
312+
\ break;\
313+
\ }\
314+
\ }\
315+
\ return res;\
316+
\ }\
317+
\ }\
318+
\}" :: forall a. (a -> a -> Boolean) -> [a] -> [[a]]
319+
320+
foreign import span
321+
"function span (p) {\
322+
\ return function (arr) {\
323+
\ var res = {init: [], rest: []};\
324+
\ for (var i = 0, len = arr.length; i < len; i++) {\
325+
\ if (p(arr[i])) {\
326+
\ res.init.push(arr[i]);\
327+
\ } else {\
328+
\ res.rest = arr.slice(i);\
329+
\ break;\
330+
\ }\
331+
\ }\
332+
\ return res;\
333+
\ }\
334+
\}" :: forall a. (a -> Boolean) -> [a] -> { init :: [a], rest :: [a] }
301335

302336
instance functorArray :: Functor [] where
303337
(<$>) = map

0 commit comments

Comments
 (0)