Skip to content

Commit a06902f

Browse files
Add Array.removeOption and Chunk.removeOption
1 parent b2b17d6 commit a06902f

File tree

5 files changed

+65
-0
lines changed

5 files changed

+65
-0
lines changed

.changeset/six-pumpkins-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": minor
3+
---
4+
5+
Add Array.removeOption and Chunk.removeOption

packages/effect/src/Array.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,36 @@ export const remove: {
12801280
return out
12811281
})
12821282

1283+
/**
1284+
* Delete the element at the specified index, creating a new `Array`,
1285+
* or return `None` if the index is out of bounds.
1286+
*
1287+
* @example
1288+
* ```ts
1289+
* import { Array, Option } from "effect"
1290+
*
1291+
* const numbers = [1, 2, 3, 4]
1292+
* const result = Array.removeOption(numbers, 2)
1293+
* assert.deepStrictEqual(result, Option.some([1, 2, 4]))
1294+
*
1295+
* const outOfBoundsResult = Array.removeOption(numbers, 5)
1296+
* assert.deepStrictEqual(outOfBoundsResult, Option.none())
1297+
* ```
1298+
*
1299+
* @since 3.13.0
1300+
*/
1301+
export const removeOption: {
1302+
(i: number): <A>(self: Iterable<A>) => Option<Array<A>>
1303+
<A>(self: Iterable<A>, i: number): Option<Array<A>>
1304+
} = dual(2, <A>(self: Iterable<A>, i: number): Option<Array<A>> => {
1305+
const out = Array.from(self)
1306+
if (isOutOfBound(i, out)) {
1307+
return O.none()
1308+
}
1309+
out.splice(i, 1)
1310+
return O.some(out)
1311+
})
1312+
12831313
/**
12841314
* Reverse an `Iterable`, creating a new `Array`.
12851315
*

packages/effect/src/Chunk.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,17 @@ export const remove: {
12351235
<A>(self: Chunk<A>, i: number): Chunk<A> => unsafeFromArray(RA.remove(toReadonlyArray(self), i))
12361236
)
12371237

1238+
/**
1239+
* @since 3.13.0
1240+
*/
1241+
export const removeOption: {
1242+
(i: number): <A>(self: Chunk<A>) => Option<Chunk<A>>
1243+
<A>(self: Chunk<A>, i: number): Option<Chunk<A>>
1244+
} = dual(
1245+
2,
1246+
<A>(self: Chunk<A>, i: number): Option<Chunk<A>> => O.map(RA.removeOption(toReadonlyArray(self), i), unsafeFromArray)
1247+
)
1248+
12381249
/**
12391250
* @since 2.0.0
12401251
*/

packages/effect/test/Array.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,20 @@ describe("Array", () => {
452452
deepStrictEqual(pipe(new Set([1, 2, 3]), Arr.remove(10)), [1, 2, 3])
453453
})
454454

455+
it("removeOption", () => {
456+
assertSome(pipe([1, 2, 3], Arr.removeOption(0)), [2, 3])
457+
// out of bound
458+
assertNone(pipe([], Arr.removeOption(0)))
459+
assertNone(pipe([1, 2, 3], Arr.removeOption(-1)))
460+
assertNone(pipe([1, 2, 3], Arr.removeOption(10)))
461+
462+
assertSome(pipe(new Set([1, 2, 3]), Arr.removeOption(0)), [2, 3])
463+
// out of bound
464+
assertNone(pipe(new Set([]), Arr.removeOption(0)))
465+
assertNone(pipe(new Set([1, 2, 3]), Arr.removeOption(-1)))
466+
assertNone(pipe(new Set([1, 2, 3]), Arr.removeOption(10)))
467+
})
468+
455469
it("reverse", () => {
456470
deepStrictEqual(Arr.reverse([]), [])
457471
deepStrictEqual(Arr.reverse([1]), [1])

packages/effect/test/Chunk.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ describe("Chunk", () => {
116116
assertEquals(pipe(Chunk.make(1, 2, 3), Chunk.remove(0)), Chunk.make(2, 3))
117117
})
118118

119+
it("removeOption", () => {
120+
assertNone(pipe(Chunk.empty(), Chunk.removeOption(0)))
121+
assertSome(pipe(Chunk.make(1, 2, 3), Chunk.removeOption(0)), Chunk.make(2, 3))
122+
})
123+
119124
it("chunksOf", () => {
120125
assertEquals(pipe(Chunk.empty(), Chunk.chunksOf(2)), Chunk.empty())
121126
assertEquals(

0 commit comments

Comments
 (0)