Skip to content

Commit da87cc6

Browse files
committed
introduced rangeWithStep', that works on a mutable array and takes a mapping function
1 parent df12529 commit da87cc6

File tree

2 files changed

+57
-46
lines changed

2 files changed

+57
-46
lines changed

src/Data/Array.purs

+48-41
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ module Data.Array
3333
, singleton
3434
, (..), range
3535
, rangeWithStep
36+
, rangeWithStep'
3637
, replicate
3738
, some
3839
, many
@@ -89,7 +90,7 @@ module Data.Array
8990
, scanr
9091

9192
, sliding
92-
, slidingWithSizeAndStep
93+
, slidingSizeStep
9394
, sort
9495
, sortBy
9596
, sortWith
@@ -1308,23 +1309,19 @@ sliding l = zip l (drop 1 l)
13081309
-- |
13091310
-- | ```purescript
13101311
-- | > import Data.Array (range)
1311-
-- | > slidingWithSizeAndStep 3 2 (range 0 10) = [[0,1,2],[2,3,4],[4,5,6],[6,7,8],[8,9,10],[10]]
1312-
-- | > slidingWithSizeAndStep 3 3 (range 0 10) = [[0,1,2],[3,4,5],[6,7,8],[9,10]]
1312+
-- | > slidingSizeStep 3 2 (range 0 10) = [[0,1,2],[2,3,4],[4,5,6],[6,7,8],[8,9,10],[10]]
1313+
-- | > slidingSizeStep 3 3 (range 0 10) = [[0,1,2],[3,4,5],[6,7,8],[9,10]]
13131314
-- | ```
13141315
-- |
1315-
slidingWithSizeAndStep :: forall a. Int -> Int -> Array a -> Array (Array a)
1316-
slidingWithSizeAndStep size step array =
1317-
let
1318-
maxIndex = (length array) - 1
1316+
slidingSizeStep :: forall a. Int -> Int -> Array a -> Array (NonEmptyArray a)
1317+
slidingSizeStep size step array
1318+
| size <= 0 || step <= 0 = [] {- args not valid -}
1319+
| otherwise =
1320+
let
1321+
maxIndex = (length array) - 1
1322+
in
1323+
rangeWithStep' 0 maxIndex step (\i -> NonEmptyArray (slice i (i + size) array))
13191324

1320-
indices = rangeWithStep 0 maxIndex step
1321-
1322-
isValid = size > 0 && step > 0
1323-
in
1324-
if isValid then
1325-
indices <#> \i -> slice i (i + size) array
1326-
else
1327-
[]
13281325

13291326
-- | Create an array containing a range of integers with a given step size, including both endpoints.
13301327
-- | Illegal arguments result in an empty Array.
@@ -1335,29 +1332,39 @@ slidingWithSizeAndStep size step array =
13351332
-- | ```
13361333
-- |
13371334
rangeWithStep :: Int -> Int -> Int -> Array Int
1338-
rangeWithStep start endIndex step =
1339-
let
1340-
isValid =
1341-
step /= 0
1342-
&& if endIndex >= start then
1343-
step > 0
1344-
else
1345-
step < 0
1346-
1347-
hasReachedEnd curr =
1348-
if step > 0 then
1349-
curr > endIndex
1350-
else
1351-
curr < endIndex
1352-
1353-
helper :: Int -> Array Int -> Array Int
1354-
helper currentIndex acc =
1355-
if hasReachedEnd currentIndex then
1356-
acc
1357-
else
1358-
helper (currentIndex + step) (snoc acc currentIndex)
1359-
in
1360-
if isValid then
1361-
helper start []
1362-
else
1363-
[]
1335+
rangeWithStep start end step = rangeWithStep' start end step identity
1336+
1337+
-- | Helper function to produce an array of elements like `rangeWithStep` with start, end and step, but immediatelly mapping over the result to work on one single mutable array.
1338+
-- |
1339+
-- | ```purescript
1340+
-- | > rangeWithStep' 0 6 2 identity = [0,2,4,6]
1341+
-- | > rangeWithStep' 0 6 2 (add 3) = [3,5,7,9]
1342+
-- | ```
1343+
rangeWithStep' :: forall t. Int -> Int -> Int -> (Int -> t) -> Array t
1344+
rangeWithStep' start end step fn =
1345+
STA.run
1346+
( do
1347+
let
1348+
isValid =
1349+
step /= 0
1350+
&& if end >= start then
1351+
step > 0
1352+
else
1353+
step < 0
1354+
1355+
hasReachedEnd current =
1356+
if step > 0 then
1357+
current > end
1358+
else
1359+
current < end
1360+
1361+
helper current acc =
1362+
if hasReachedEnd current then
1363+
pure acc
1364+
else do
1365+
void $ STA.push (fn current) acc
1366+
helper (current + step) acc
1367+
arr <- STA.new
1368+
void $ helper start arr
1369+
pure arr
1370+
)

test/Test/Data/Array.purs

+9-5
Original file line numberDiff line numberDiff line change
@@ -470,18 +470,22 @@ testArray = do
470470
log "sliding"
471471
assert $ A.sliding [ 1, 2, 3, 4, 5 ] == [ (Tuple 1 2), (Tuple 2 3), (Tuple 3 4), (Tuple 4 5) ]
472472

473-
log "slidingWithStepAndSize"
474-
assert $ A.slidingWithSizeAndStep 3 2 (A.range 0 10) == [[0,1,2],[2,3,4],[4,5,6],[6,7,8],[8,9,10],[10]]
475-
assert $ A.slidingWithSizeAndStep 3 3 (A.range 0 10) == [[0,1,2],[3,4,5],[6,7,8],[9,10]]
476-
assert $ A.slidingWithSizeAndStep 3 (-2) (A.range 0 10) == []
477-
assert $ A.slidingWithSizeAndStep (-3) (2) (A.range 0 10) == []
473+
log "slidingSizeStep"
474+
assert $ A.slidingSizeStep 3 2 (A.range 0 10) == ([[0,1,2],[2,3,4],[4,5,6],[6,7,8],[8,9,10],[10]] <#> nea)
475+
assert $ A.slidingSizeStep 3 3 (A.range 0 10) == ([[0,1,2],[3,4,5],[6,7,8],[9,10]] <#> nea)
476+
assert $ A.slidingSizeStep 3 (-2) (A.range 0 10) == []
477+
assert $ A.slidingSizeStep (-3) (2) (A.range 0 10) == []
478478

479479
log "rangeWithStep"
480480
assert $ A.rangeWithStep 0 6 2 == [ 0, 2, 4, 6 ]
481481
assert $ A.rangeWithStep 0 (-6) (-2) == [ 0, -2, -4, -6 ]
482482
assert $ A.rangeWithStep 0 6 (-2) == []
483483
assert $ A.rangeWithStep 0 (-6) (2) == []
484484

485+
log "rangeWithStep'"
486+
assert $ A.rangeWithStep 0 6 2 == A.rangeWithStep' 0 6 2 identity
487+
assert $ A.rangeWithStep' 0 6 2 (add 3) == [3, 5, 7, 9]
488+
485489
nea :: Array ~> NEA.NonEmptyArray
486490
nea = unsafePartial fromJust <<< NEA.fromArray
487491

0 commit comments

Comments
 (0)