Skip to content

Commit

Permalink
feat(Array): add shuffle & swap fns
Browse files Browse the repository at this point in the history
  • Loading branch information
Thanga-Ganapathy committed Apr 21, 2024
1 parent e99131c commit 7a05b94
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/angry-elephants-press.md
@@ -0,0 +1,5 @@
---
"@opentf/std": minor
---

Added array shuffle & swap functions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -157,8 +157,10 @@ compose(
- [move](https://js-std.pages.dev/Array/move)
- [range](https://js-std.pages.dev/Array/range)
- [reverse](https://js-std.pages.dev/Array/reverse)
- [shuffle](https://js-std.pages.dev/Array/shuffle)
- [sort](https://js-std.pages.dev/Array/sort)
- [sortBy](https://js-std.pages.dev/Array/sortBy)
- [swap](https://js-std.pages.dev/Array/swap)
- [symDiff](https://js-std.pages.dev/Array/symDiff)
- [take](https://js-std.pages.dev/Array/take)
- [union](https://js-std.pages.dev/Array/union)
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/pages/Array/_meta.json
Expand Up @@ -16,8 +16,10 @@
"move": "move",
"range": "range",
"reverse": "reverse",
"shuffle": "shuffle",
"sort": "sort",
"sortBy": "sortBy",
"swap": "swap",
"symDiff": "symDiff",
"take": "take",
"union": "union",
Expand Down
39 changes: 39 additions & 0 deletions apps/docs/pages/Array/shuffle.mdx
@@ -0,0 +1,39 @@
import { Callout } from "nextra/components";
import REPL from "../../components/REPL";

> Shuffles the given array values.
<Callout emoji="" type="info">
Immutable: This does not mutate the given array.
</Callout>

## Syntax

```ts
import { shuffle } from '@opentf/std';

shuffle<T>(arr: T[]): T[]
```

## Examples

```ts
shuffle([]) //=> []

shuffle([1]) //=> [1]

shuffle([1, 2, 3, 4, 5]) //=> [ 2, 4, 5, 1, 3 ]

shuffle('Apple') //=> [ 'p', 'e', 'A', 'l', 'p' ]
```

## Try

<REPL code={`const { shuffle } = require('@opentf/std');
shuffle([1, 2, 3, 4, 5]);
`} />

## Learn

- [Fisher–Yates shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)
51 changes: 51 additions & 0 deletions apps/docs/pages/Array/swap.mdx
@@ -0,0 +1,51 @@
import { Callout } from "nextra/components";
import REPL from "../../components/REPL";

> Swaps two elements in an array.
<Callout emoji="" type="info">
Immutable: This does not mutate the given array.
</Callout>

## Syntax

```ts
import { swap } from '@opentf/std';

swap<T>(arr: T[], x: number, y: number): T[]
```

## Examples

```ts
swap([], 0, 0) //=> []

swap([], 0, 1) //=> []

swap([0], 0, 1) //=> [undefined, 0]

swap([1, 2, 3], 1, 2) //=> [1, 3, 2]

swap([1, 2, 3], 1, 5) //=> [1, undefined, 3, , , 2]

const arr = [{ a: 1 }, { b: 'a' }, { c: [5] }];
swap(arr, 0, 2)
//=> [
// {
// c: [5],
// },
// {
// b: 'a',
// },
// {
// a: 1,
// },
// ]
```

## Try

<REPL code={`const { swap } = require('@opentf/std');
swap([1, 2, 3], 1, 2);
`} />
2 changes: 2 additions & 0 deletions packages/std/README.md
Expand Up @@ -157,8 +157,10 @@ compose(
- [move](https://js-std.pages.dev/Array/move)
- [range](https://js-std.pages.dev/Array/range)
- [reverse](https://js-std.pages.dev/Array/reverse)
- [shuffle](https://js-std.pages.dev/Array/shuffle)
- [sort](https://js-std.pages.dev/Array/sort)
- [sortBy](https://js-std.pages.dev/Array/sortBy)
- [swap](https://js-std.pages.dev/Array/swap)
- [symDiff](https://js-std.pages.dev/Array/symDiff)
- [take](https://js-std.pages.dev/Array/take)
- [union](https://js-std.pages.dev/Array/union)
Expand Down
18 changes: 18 additions & 0 deletions packages/std/__tests__/array/shuffle.spec.ts
@@ -0,0 +1,18 @@
import { shuffle } from '../../src';

describe('Array > shuffle', () => {
test('empty array', () => {
expect(shuffle([])).toEqual([]);
});

test('single element array', () => {
expect(shuffle([1])).toEqual([1]);
});

test('array of numbers', () => {
const arr = [1, 2, 3, 4, 5];
expect(shuffle(arr)).toEqual(expect.arrayContaining([1, 2, 3, 4, 5]));
expect(shuffle(arr)).not.toEqual([1, 2, 3, 4, 5]);
expect(arr).toEqual([1, 2, 3, 4, 5]);
});
});
38 changes: 38 additions & 0 deletions packages/std/__tests__/array/swap.spec.ts
@@ -0,0 +1,38 @@
import { swap } from '../../src';

describe('Array > swap', () => {
test('empty array', () => {
expect(swap([], 0, 0)).toEqual([]);
});

test('immutable', () => {
const arr = [1, 2, 3];
expect(swap(arr, 1, 2)).toEqual([1, 3, 2]);
expect(arr).toEqual([1, 2, 3]);
});

test('swap 0 index to 1', () => {
expect(swap([], 0, 1)).toEqual([]);
expect(swap([0], 0, 1)).toEqual([undefined, 0]);
expect(swap([0, 1], 0, 1)).toEqual([1, 0]);
});

test('swap index > length', () => {
expect(swap([1, 2, 3], 1, 5)).toEqual([1, undefined, 3, , , 2]);
});

test('array of objects', () => {
const arr = [{ a: 1 }, { b: 'a' }, { c: [5] }];
expect(swap(arr, 0, 2)).toEqual([
{
c: [5],
},
{
b: 'a',
},
{
a: 1,
},
]);
});
});
21 changes: 21 additions & 0 deletions packages/std/src/array/shuffle.ts
@@ -0,0 +1,21 @@
/**
* Shuffles the given array values.
*
* shuffle([1, 2, 3]) //=> [3, 1, 2]
*/

export default function shuffle<T>(arr: T[]): T[] {
const a = [...arr];
let i = a.length,
randIdx,
t;

while (i) {
randIdx = Math.floor(Math.random() * i--);
t = a[i];
a[i] = a[randIdx];
a[randIdx] = t;
}

return a;
}
15 changes: 15 additions & 0 deletions packages/std/src/array/swap.ts
@@ -0,0 +1,15 @@
/**
* Swaps two elements in an array.
*
* @example
* swap([1, 2, 3, 4, 5], 0, 1) //=> [2, 1, 3, 4, 5]
*/
export default function swap<T>(arr: T[], x: number, y: number): T[] {
const a = [...arr];
const b = a[y];

a[y] = a[x];
a[x] = b;

return a;
}
2 changes: 2 additions & 0 deletions packages/std/src/index.ts
Expand Up @@ -31,6 +31,8 @@ export { default as take } from './array/take';
export { default as drop } from './array/drop';
export { default as intersperse } from './array/intersperse';
export { default as reverse } from './array/reverse';
export { default as shuffle } from './array/shuffle';
export { default as swap } from './array/swap';

// Async
export { default as aFilter } from './async/aFilter';
Expand Down

0 comments on commit 7a05b94

Please sign in to comment.