Skip to content

Commit 7a05b94

Browse files
feat(Array): add shuffle & swap fns
1 parent e99131c commit 7a05b94

File tree

11 files changed

+195
-0
lines changed

11 files changed

+195
-0
lines changed

.changeset/angry-elephants-press.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@opentf/std": minor
3+
---
4+
5+
Added array shuffle & swap functions.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ compose(
157157
- [move](https://js-std.pages.dev/Array/move)
158158
- [range](https://js-std.pages.dev/Array/range)
159159
- [reverse](https://js-std.pages.dev/Array/reverse)
160+
- [shuffle](https://js-std.pages.dev/Array/shuffle)
160161
- [sort](https://js-std.pages.dev/Array/sort)
161162
- [sortBy](https://js-std.pages.dev/Array/sortBy)
163+
- [swap](https://js-std.pages.dev/Array/swap)
162164
- [symDiff](https://js-std.pages.dev/Array/symDiff)
163165
- [take](https://js-std.pages.dev/Array/take)
164166
- [union](https://js-std.pages.dev/Array/union)

apps/docs/pages/Array/_meta.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
"move": "move",
1717
"range": "range",
1818
"reverse": "reverse",
19+
"shuffle": "shuffle",
1920
"sort": "sort",
2021
"sortBy": "sortBy",
22+
"swap": "swap",
2123
"symDiff": "symDiff",
2224
"take": "take",
2325
"union": "union",

apps/docs/pages/Array/shuffle.mdx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Callout } from "nextra/components";
2+
import REPL from "../../components/REPL";
3+
4+
> Shuffles the given array values.
5+
6+
<Callout emoji="" type="info">
7+
Immutable: This does not mutate the given array.
8+
</Callout>
9+
10+
## Syntax
11+
12+
```ts
13+
import { shuffle } from '@opentf/std';
14+
15+
shuffle<T>(arr: T[]): T[]
16+
```
17+
18+
## Examples
19+
20+
```ts
21+
shuffle([]) //=> []
22+
23+
shuffle([1]) //=> [1]
24+
25+
shuffle([1, 2, 3, 4, 5]) //=> [ 2, 4, 5, 1, 3 ]
26+
27+
shuffle('Apple') //=> [ 'p', 'e', 'A', 'l', 'p' ]
28+
```
29+
30+
## Try
31+
32+
<REPL code={`const { shuffle } = require('@opentf/std');
33+
34+
shuffle([1, 2, 3, 4, 5]);
35+
`} />
36+
37+
## Learn
38+
39+
- [Fisher–Yates shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)

apps/docs/pages/Array/swap.mdx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Callout } from "nextra/components";
2+
import REPL from "../../components/REPL";
3+
4+
> Swaps two elements in an array.
5+
6+
<Callout emoji="" type="info">
7+
Immutable: This does not mutate the given array.
8+
</Callout>
9+
10+
## Syntax
11+
12+
```ts
13+
import { swap } from '@opentf/std';
14+
15+
swap<T>(arr: T[], x: number, y: number): T[]
16+
```
17+
18+
## Examples
19+
20+
```ts
21+
swap([], 0, 0) //=> []
22+
23+
swap([], 0, 1) //=> []
24+
25+
swap([0], 0, 1) //=> [undefined, 0]
26+
27+
swap([1, 2, 3], 1, 2) //=> [1, 3, 2]
28+
29+
swap([1, 2, 3], 1, 5) //=> [1, undefined, 3, , , 2]
30+
31+
const arr = [{ a: 1 }, { b: 'a' }, { c: [5] }];
32+
swap(arr, 0, 2)
33+
//=> [
34+
// {
35+
// c: [5],
36+
// },
37+
// {
38+
// b: 'a',
39+
// },
40+
// {
41+
// a: 1,
42+
// },
43+
// ]
44+
```
45+
46+
## Try
47+
48+
<REPL code={`const { swap } = require('@opentf/std');
49+
50+
swap([1, 2, 3], 1, 2);
51+
`} />

packages/std/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ compose(
157157
- [move](https://js-std.pages.dev/Array/move)
158158
- [range](https://js-std.pages.dev/Array/range)
159159
- [reverse](https://js-std.pages.dev/Array/reverse)
160+
- [shuffle](https://js-std.pages.dev/Array/shuffle)
160161
- [sort](https://js-std.pages.dev/Array/sort)
161162
- [sortBy](https://js-std.pages.dev/Array/sortBy)
163+
- [swap](https://js-std.pages.dev/Array/swap)
162164
- [symDiff](https://js-std.pages.dev/Array/symDiff)
163165
- [take](https://js-std.pages.dev/Array/take)
164166
- [union](https://js-std.pages.dev/Array/union)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { shuffle } from '../../src';
2+
3+
describe('Array > shuffle', () => {
4+
test('empty array', () => {
5+
expect(shuffle([])).toEqual([]);
6+
});
7+
8+
test('single element array', () => {
9+
expect(shuffle([1])).toEqual([1]);
10+
});
11+
12+
test('array of numbers', () => {
13+
const arr = [1, 2, 3, 4, 5];
14+
expect(shuffle(arr)).toEqual(expect.arrayContaining([1, 2, 3, 4, 5]));
15+
expect(shuffle(arr)).not.toEqual([1, 2, 3, 4, 5]);
16+
expect(arr).toEqual([1, 2, 3, 4, 5]);
17+
});
18+
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { swap } from '../../src';
2+
3+
describe('Array > swap', () => {
4+
test('empty array', () => {
5+
expect(swap([], 0, 0)).toEqual([]);
6+
});
7+
8+
test('immutable', () => {
9+
const arr = [1, 2, 3];
10+
expect(swap(arr, 1, 2)).toEqual([1, 3, 2]);
11+
expect(arr).toEqual([1, 2, 3]);
12+
});
13+
14+
test('swap 0 index to 1', () => {
15+
expect(swap([], 0, 1)).toEqual([]);
16+
expect(swap([0], 0, 1)).toEqual([undefined, 0]);
17+
expect(swap([0, 1], 0, 1)).toEqual([1, 0]);
18+
});
19+
20+
test('swap index > length', () => {
21+
expect(swap([1, 2, 3], 1, 5)).toEqual([1, undefined, 3, , , 2]);
22+
});
23+
24+
test('array of objects', () => {
25+
const arr = [{ a: 1 }, { b: 'a' }, { c: [5] }];
26+
expect(swap(arr, 0, 2)).toEqual([
27+
{
28+
c: [5],
29+
},
30+
{
31+
b: 'a',
32+
},
33+
{
34+
a: 1,
35+
},
36+
]);
37+
});
38+
});

packages/std/src/array/shuffle.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Shuffles the given array values.
3+
*
4+
* shuffle([1, 2, 3]) //=> [3, 1, 2]
5+
*/
6+
7+
export default function shuffle<T>(arr: T[]): T[] {
8+
const a = [...arr];
9+
let i = a.length,
10+
randIdx,
11+
t;
12+
13+
while (i) {
14+
randIdx = Math.floor(Math.random() * i--);
15+
t = a[i];
16+
a[i] = a[randIdx];
17+
a[randIdx] = t;
18+
}
19+
20+
return a;
21+
}

packages/std/src/array/swap.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Swaps two elements in an array.
3+
*
4+
* @example
5+
* swap([1, 2, 3, 4, 5], 0, 1) //=> [2, 1, 3, 4, 5]
6+
*/
7+
export default function swap<T>(arr: T[], x: number, y: number): T[] {
8+
const a = [...arr];
9+
const b = a[y];
10+
11+
a[y] = a[x];
12+
a[x] = b;
13+
14+
return a;
15+
}

packages/std/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export { default as take } from './array/take';
3131
export { default as drop } from './array/drop';
3232
export { default as intersperse } from './array/intersperse';
3333
export { default as reverse } from './array/reverse';
34+
export { default as shuffle } from './array/shuffle';
35+
export { default as swap } from './array/swap';
3436

3537
// Async
3638
export { default as aFilter } from './async/aFilter';

0 commit comments

Comments
 (0)