Skip to content

Commit

Permalink
feat(stdlib)!: Use Array length as default end in Array.slice funct…
Browse files Browse the repository at this point in the history
…ion (#1762)

* feat(stdlib)!: Use Array length as default end in `Array.slice` function

* chore: run formatter

Weird that the formatter didnt format on save.
  • Loading branch information
spotandjake committed Mar 19, 2023
1 parent 78a81d4 commit a698fdc
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 48 deletions.
38 changes: 20 additions & 18 deletions compiler/test/stdlib/array.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -347,19 +347,20 @@ assert Array.join(", ", [>]) == ""
// Array.slice
let testChars = [> 'a', 'b', 'c']

assert Array.slice(0, 1, testChars) == [> 'a']
assert Array.slice(1, Array.length(testChars), testChars) == [> 'b', 'c']
assert Array.slice(0, 0, testChars) == [>]
assert Array.slice(0, end=1, testChars) == [> 'a']
assert Array.slice(1, end=Array.length(testChars), testChars) == [> 'b', 'c']
assert Array.slice(1, testChars) == [> 'b', 'c']
assert Array.slice(0, end=0, testChars) == [>]
// Purposefully huge number
assert Array.slice(1, 10000, testChars) == [> 'b', 'c']
assert Array.slice(1, end=10000, testChars) == [> 'b', 'c']
// Negative indexing
assert Array.slice(1, -1, testChars) == [> 'b']
assert Array.slice(-2, -1, testChars) == [> 'b']
assert Array.slice(1, end=-1, testChars) == [> 'b']
assert Array.slice(-2, end=-1, testChars) == [> 'b']
// Bad order
assert Array.slice(2, 1, testChars) == [>]
assert Array.slice(-1, -2, testChars) == [>]
assert Array.slice(2, end=1, testChars) == [>]
assert Array.slice(-1, end=-2, testChars) == [>]
// Empty
assert Array.slice(1, 4, [>]) == [>]
assert Array.slice(1, end=4, [>]) == [>]

// Array.sort
// Numbers
Expand Down Expand Up @@ -780,20 +781,21 @@ module Immutable {
// Array.slice
let testChars = fromList(['a', 'b', 'c'])

assert Array.slice(0, 1, testChars) == fromList(['a'])
assert Array.slice(1, Array.length(testChars), testChars) ==
assert Array.slice(0, end=1, testChars) == fromList(['a'])
assert Array.slice(1, end=Array.length(testChars), testChars) ==
fromList(['b', 'c'])
assert Array.slice(0, 0, testChars) == fromList([])
assert Array.slice(1, testChars) == fromList(['b', 'c'])
assert Array.slice(0, end=0, testChars) == fromList([])
// Purposefully huge number
assert Array.slice(1, 10000, testChars) == fromList(['b', 'c'])
assert Array.slice(1, end=10000, testChars) == fromList(['b', 'c'])
// Negative indexing
assert Array.slice(1, -1, testChars) == fromList(['b'])
assert Array.slice(-2, -1, testChars) == fromList(['b'])
assert Array.slice(1, end=-1, testChars) == fromList(['b'])
assert Array.slice(-2, end=-1, testChars) == fromList(['b'])
// Bad order
assert Array.slice(2, 1, testChars) == fromList([])
assert Array.slice(-1, -2, testChars) == fromList([])
assert Array.slice(2, end=1, testChars) == fromList([])
assert Array.slice(-1, end=-2, testChars) == fromList([])
// Empty
assert Array.slice(1, 4, fromList([])) == fromList([])
assert Array.slice(1, end=4, fromList([])) == fromList([])

// Array.sort
// Numbers
Expand Down
50 changes: 28 additions & 22 deletions stdlib/array.gr
Original file line number Diff line number Diff line change
Expand Up @@ -904,17 +904,18 @@ let wrapNegativeIndex = (arrLen, idx) => {
* If either index is a negative number, it will be treated as a reverse index from
* the end of the array. e.g. `slice(1, -1, [> 'a', 'b', 'c']) == [> 'b']`.
*
* @param startIndex: The index of the array where the slice will begin (inclusive)
* @param endIndex: The index of the array where the slice will end (exclusive)
* @param start: The index of the array where the slice will begin (inclusive)
* @param end: The index of the array where the slice will end (exclusive)
* @param array: The array to be sliced
* @returns The subset of the array that was sliced
*
* @since v0.4.0
* @history v0.6.0: Default `end` to the Array length
*/
provide let slice = (startIndex, endIndex, array) => {
provide let slice = (start, end=length(array), array) => {
let arrayLength = length(array)
let startIndex = wrapNegativeIndex(arrayLength, startIndex)
let endIndex = wrapNegativeIndex(arrayLength, endIndex)
let startIndex = wrapNegativeIndex(arrayLength, start)
let endIndex = wrapNegativeIndex(arrayLength, end)
// Ensure we aren't working with an `end` value that is too big
let endIndex = if (endIndex > arrayLength) {
arrayLength
Expand Down Expand Up @@ -1016,7 +1017,7 @@ provide let rotate = (n, arr) => {

/**
* An immutable array implementation.
*
*
* @since v0.6.0
* @history v0.5.4: Originally in `"immutablearray"` module
*/
Expand Down Expand Up @@ -1103,7 +1104,7 @@ provide module Immutable {

/**
* An empty array.
*
*
* @since v0.6.0
* @history v0.5.4: Originally in `"immutablearray"` module
*/
Expand All @@ -1115,7 +1116,7 @@ provide module Immutable {

/**
* Determines if the array contains no elements.
*
*
* @param array: The array to check
* @returns `true` if the array is empty and `false` otherwise
*
Expand Down Expand Up @@ -1161,7 +1162,7 @@ provide module Immutable {

let numToAppend = Number.min(len2, branchingFactor - len1)
let toAppend = if (numToAppend < len2) {
mutSlice(0, numToAppend, array2)
mutSlice(0, end=numToAppend, array2)
} else {
array2
}
Expand All @@ -1188,7 +1189,7 @@ provide module Immutable {
* @param array: The array to access
* @returns The element from the array
* @throws IndexOutOfBounds: When the index being accessed is outside the array's bounds
*
*
* @example get(1, fromList([1, 2, 3, 4])) == 2
* @example get(-1, fromList([1, 2, 3, 4])) == 4
*
Expand Down Expand Up @@ -1226,7 +1227,7 @@ provide module Immutable {
* @param array: The array to update
* @returns A new array containing the new element at the given index
* @throws IndexOutOfBounds: When the index being updated is outside the array's bounds
*
*
* @example set(1, 9, fromList([1, 2, 3, 4, 5])) == fromList([1, 9, 3, 4, 5])
*
* @since v0.6.0
Expand Down Expand Up @@ -1304,7 +1305,11 @@ provide module Immutable {
let newArray = replaceTail(appended, array)
if (numNotAppended > 0) {
let appendLen = mutLength(toAppend)
let newTail = mutSlice(appendLen - numNotAppended, appendLen, toAppend)
let newTail = mutSlice(
appendLen - numNotAppended,
end=appendLen,
toAppend
)
replaceTail(newTail, newArray)
} else {
newArray
Expand Down Expand Up @@ -1378,7 +1383,7 @@ provide module Immutable {
if (numNotAppended >= 0) {
let appendLen = mutLength(toAppend)
{
btail: mutSlice(appendLen - numNotAppended, appendLen, toAppend),
btail: mutSlice(appendLen - numNotAppended, end=appendLen, toAppend),
nodes: [Leaf(appended), ...nodes],
numNodes: numNodes + 1,
}
Expand Down Expand Up @@ -1432,7 +1437,7 @@ provide module Immutable {
*
* @param arrays: A list containing all arrays to combine
* @returns The new array
*
*
* @example concat([fromList([1, 2]), fromList([3, 4]), fromList([5, 6])]) == fromList([1, 2, 3, 4, 5, 6])
*
* @since v0.6.0
Expand Down Expand Up @@ -1628,7 +1633,7 @@ provide module Immutable {
* @param fn: The function to be called on each element, where the value returned will be an array that gets appended to the new array
* @param array: The array to iterate
* @returns The new array
*
*
* @example flatMap(n => fromList([n, n + 1]), fromList([1, 3, 5])) == fromList([1, 2, 3, 4, 5, 6])
*
* @since v0.6.0
Expand Down Expand Up @@ -1850,7 +1855,7 @@ provide module Immutable {
*
* Calling this function with arrays of different sizes will cause the returned
* array to have the length of the smaller array.
*
*
* @param array1: The array to provide values for the first tuple element
* @param array2: The array to provide values for the second tuple element
* @returns The new array containing indexed pairs of `(a, b)`
Expand All @@ -1869,7 +1874,7 @@ provide module Immutable {
* applying the function to the first elements of each array, the second element
* will contain the result of applying the function to the second elements of
* each array, and so on.
*
*
* Calling this function with arrays of different sizes will cause the returned
* array to have the length of the smaller array.
*
Expand All @@ -1880,7 +1885,7 @@ provide module Immutable {
*
* @example zipWith((a, b) => a + b, fromList([1, 2, 3]), fromList([4, 5, 6])) == fromList([5, 7, 9])
* @example zipWith((a, b) => a * b, fromList([1, 2, 3]), fromList([4, 5])) == fromList([4, 10])
*
*
* @since v0.6.0
* @history v0.5.4: Originally in `"immutablearray"` module
*/
Expand Down Expand Up @@ -1944,15 +1949,16 @@ provide module Immutable {
* @param end: The index of the array where the slice will end (exclusive)
* @param array: The array to be sliced
* @returns The subset of the array that was sliced
*
*
* @example slice(0, 2, fromList(['a', 'b', 'c'])) == fromList(['a', 'b'])
* @example slice(1, -1, fromList(['a', 'b', 'c'])) == fromList(['b'])
*
* @since v0.6.0
* @history v0.5.4: Originally in `"immutablearray"` module
* @history v0.6.0: Default `end` to the Array length
*/

provide let slice = (start, end, array) => {
provide let slice = (start, end=length(array), array) => {
let begin = clampIndex(array.length, start)
let end = clampIndex(array.length, end)
let mut i = array.length
Expand Down Expand Up @@ -1999,8 +2005,8 @@ provide module Immutable {

provide let rotate = (n, array) => {
let sliceI = if (array.length == 0) 0 else n % array.length
let before = slice(0, sliceI, array)
let after = slice(sliceI, array.length, array)
let before = slice(0, end=sliceI, array)
let after = slice(sliceI, end=array.length, array)
append(after, before)
}
}
25 changes: 17 additions & 8 deletions stdlib/array.md
Original file line number Diff line number Diff line change
Expand Up @@ -1189,13 +1189,20 @@ Returns:

### Array.**slice**

<details disabled>
<summary tabindex="-1">Added in <code>0.4.0</code></summary>
No other changes yet.
<details>
<summary>Added in <code>0.4.0</code></summary>
<table>
<thead>
<tr><th>version</th><th>changes</th></tr>
</thead>
<tbody>
<tr><td><code>next</code></td><td>Default `end` to the Array length</td></tr>
</tbody>
</table>
</details>

```grain
slice : (startIndex: Number, endIndex: Number, array: Array<a>) -> Array<a>
slice : (start: Number, ?end: Number, array: Array<a>) -> Array<a>
```

Slices an array given zero-based start and end indexes. The value
Expand All @@ -1208,8 +1215,8 @@ Parameters:

|param|type|description|
|-----|----|-----------|
|`startIndex`|`Number`|The index of the array where the slice will begin (inclusive)|
|`endIndex`|`Number`|The index of the array where the slice will end (exclusive)|
|`start`|`Number`|The index of the array where the slice will begin (inclusive)|
|`end`|`Option<Number>`|The index of the array where the slice will end (exclusive)|
|`array`|`Array<a>`|The array to be sliced|

Returns:
Expand Down Expand Up @@ -2455,13 +2462,15 @@ Returns:
</thead>
<tbody>
<tr><td><code>0.5.4</code></td><td>Originally in `"immutablearray"` module</td></tr>
<tr><td><code>next</code></td><td>Default `end` to the Array length</td></tr>
</tbody>
</table>
</details>

```grain
slice :
(start: Number, end: Number, array: ImmutableArray<a>) -> ImmutableArray<a>
(start: Number, ?end: Number, array: ImmutableArray<a>) ->
ImmutableArray<a>
```

Slices an array given zero-based start and end indexes. The value
Expand All @@ -2475,7 +2484,7 @@ Parameters:
|param|type|description|
|-----|----|-----------|
|`start`|`Number`|The index of the array where the slice will begin (inclusive)|
|`end`|`Number`|The index of the array where the slice will end (exclusive)|
|`end`|`Option<Number>`|The index of the array where the slice will end (exclusive)|
|`array`|`ImmutableArray<a>`|The array to be sliced|

Returns:
Expand Down

0 comments on commit a698fdc

Please sign in to comment.