@@ -33,6 +33,7 @@ module Data.Array
33
33
, singleton
34
34
, (..), range
35
35
, rangeWithStep
36
+ , rangeWithStep'
36
37
, replicate
37
38
, some
38
39
, many
@@ -89,7 +90,7 @@ module Data.Array
89
90
, scanr
90
91
91
92
, sliding
92
- , slidingWithSizeAndStep
93
+ , slidingSizeStep
93
94
, sort
94
95
, sortBy
95
96
, sortWith
@@ -1308,23 +1309,19 @@ sliding l = zip l (drop 1 l)
1308
1309
-- |
1309
1310
-- | ```purescript
1310
1311
-- | > 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]]
1313
1314
-- | ```
1314
1315
-- |
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))
1319
1324
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
- []
1328
1325
1329
1326
-- | Create an array containing a range of integers with a given step size, including both endpoints.
1330
1327
-- | Illegal arguments result in an empty Array.
@@ -1335,29 +1332,39 @@ slidingWithSizeAndStep size step array =
1335
1332
-- | ```
1336
1333
-- |
1337
1334
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
+ )
0 commit comments