Skip to content

Commit fba7c1d

Browse files
authored
feat(stdlib): Add chunk function to Array module (#1708)
* feat: Add `Array.Chunk` * chore: Apply suggestions from code review * chore: Use an exception for array length 0 * chore: Remove Partial Behaviour * chore: use optional argument on slice * chore: Run formatter * chore: apply changes from code review
1 parent 3c3c4d9 commit fba7c1d

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed

compiler/test/stdlib/array.test.gr

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,16 @@ let arr9 = [>]
426426
Array.rotate(1, arr9)
427427
assert arr9 == [>]
428428

429+
// Array.chunk
430+
assert Array.chunk(2, [>]) == [>]
431+
assert Array.chunk(2, [> 1, 2, 3, 4]) == [> [> 1, 2], [> 3, 4]]
432+
assert Array.chunk(2, [> 1, 2, 3, 4, 5]) == [> [> 1, 2], [> 3, 4], [> 5]]
433+
assert Array.chunk(3, [> 1, 2, 3, 4, 5, 6, 7, 8]) ==
434+
[> [> 1, 2, 3], [> 4, 5, 6], [> 7, 8]]
435+
assert Array.chunk(3, [> 1, 2, 3, 4, 5, 6, 7, 8]) ==
436+
[> [> 1, 2, 3], [> 4, 5, 6], [> 7, 8]]
437+
assert Array.chunk(10, [> 1, 2, 3, 4, 5]) == [> [> 1, 2, 3, 4, 5]]
438+
429439
module Immutable {
430440
from Array use { Immutable as Array }
431441

stdlib/array.gr

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,55 @@ provide let rotate = (n, arr) => {
10201020
}
10211021
}
10221022

1023+
let rec chunkHelp = (chunkSize, arr, arrLen, chunkStartIndex) => {
1024+
if (arrLen == 0) {
1025+
[]
1026+
} else if (arrLen < chunkSize) {
1027+
[slice(chunkStartIndex, arr)]
1028+
} else {
1029+
// create the first chunk of the given array
1030+
let firstChunk = slice(
1031+
chunkStartIndex,
1032+
end=chunkStartIndex + chunkSize,
1033+
arr
1034+
)
1035+
let restChunks = chunkHelp(
1036+
chunkSize,
1037+
arr,
1038+
arrLen - chunkSize,
1039+
chunkStartIndex + chunkSize
1040+
)
1041+
[firstChunk, ...restChunks]
1042+
}
1043+
}
1044+
1045+
/**
1046+
* Splits the given array into chunks of the provided size.
1047+
* If the array cannot be split evenly, the final chunk will contain the remaining elements.
1048+
*
1049+
* @param chunkSize: The maximum size of each chunk
1050+
* @param arr: The array to chunk
1051+
* @returns An array of chunks
1052+
*
1053+
* @throws InvalidArgument(String): When `chunkSize` is not an integer
1054+
* @throws InvalidArgument(String): When `chunkSize` is less than one
1055+
*
1056+
* @example chunk(2, [> 1, 2, 3, 4, 5]) == [> [> 1, 2], [> 3, 4], [> 5] ]
1057+
* @example chunk(2, [> 1, 2, 3, 4]) == [> [> 1, 2], [> 3, 4] ]
1058+
*
1059+
* @since v0.6.0
1060+
*/
1061+
provide let chunk = (chunkSize, arr) => {
1062+
if (chunkSize <= 0) {
1063+
throw Exception.InvalidArgument("chunkSize must be greater than 0")
1064+
} else {
1065+
checkLength(chunkSize)
1066+
let arrLen = length(arr)
1067+
let chunks = chunkHelp(chunkSize, arr, arrLen, 0)
1068+
fromList(chunks)
1069+
}
1070+
}
1071+
10231072
/**
10241073
* An immutable array implementation.
10251074
*

stdlib/array.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,50 @@ let array = [> 1, 2, 3, 4, 5]; rotate(2, arr); arr == [> 3, 4, 5, 1, 2]
12881288
let array = [> 1, 2, 3, 4, 5]; rotate(-1, arr); arr == [> 5, 1, 2, 3, 4]
12891289
```
12901290

1291+
### Array.**chunk**
1292+
1293+
<details disabled>
1294+
<summary tabindex="-1">Added in <code>next</code></summary>
1295+
No other changes yet.
1296+
</details>
1297+
1298+
```grain
1299+
chunk : (chunkSize: Number, arr: Array<a>) -> Array<Array<a>>
1300+
```
1301+
1302+
Splits the given array into chunks of the provided size.
1303+
If the array cannot be split evenly, the final chunk will contain the remaining elements.
1304+
1305+
Parameters:
1306+
1307+
|param|type|description|
1308+
|-----|----|-----------|
1309+
|`chunkSize`|`Number`|The maximum size of each chunk|
1310+
|`arr`|`Array<a>`|The array to chunk|
1311+
1312+
Returns:
1313+
1314+
|type|description|
1315+
|----|-----------|
1316+
|`Array<Array<a>>`|An array of chunks|
1317+
1318+
Throws:
1319+
1320+
`InvalidArgument(String)`
1321+
1322+
* When `chunkSize` is not an integer
1323+
* When `chunkSize` is less than one
1324+
1325+
Examples:
1326+
1327+
```grain
1328+
chunk(2, [> 1, 2, 3, 4, 5]) == [> [> 1, 2], [> 3, 4], [> 5] ]
1329+
```
1330+
1331+
```grain
1332+
chunk(2, [> 1, 2, 3, 4]) == [> [> 1, 2], [> 3, 4] ]
1333+
```
1334+
12911335
## Array.Immutable
12921336

12931337
An immutable array implementation.

0 commit comments

Comments
 (0)