Skip to content

Commit 5e33aa1

Browse files
✨ feat(api): Add choice and _choice functions.
Fixes #16.
1 parent 2cebdbc commit 5e33aa1

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

src/api/choice.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import _choice from '../kernel/_choice.js';
2+
import randint from './randint.js';
3+
4+
/**
5+
* Sample a single element from an array.
6+
*
7+
* @function
8+
* @param {Array} a The input array.
9+
* @param {number} i Inclusive left bound.
10+
* @param {number} j Non-inclusive right bound.
11+
* @return {any} The sampled element.
12+
*/
13+
const choice = _choice(randint);
14+
export default choice;

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
export {default as choice} from './api/choice.js';
12
export {default as randfloat} from './api/randfloat.js';
23
export {default as randint} from './api/randint.js';
34
export {default as random} from './api/random.js';
45
export {default as randrange} from './api/randrange.js';
56
export {default as sample} from './api/sample.js';
67
export {default as shuffle} from './api/shuffle.js';
8+
export {default as _choice} from './kernel/_choice.js';
79
export {default as _fisheryates} from './kernel/_fisheryates.js';
810
export {default as _randfloat} from './kernel/_randfloat.js';
911
export {default as _randint} from './kernel/_randint.js';

src/kernel/_choice.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Builds a choice function given a randint function.
3+
*
4+
* @param {Function} randint The randint function.
5+
* @return {Function} The choice function.
6+
*/
7+
const _choice = (randint) => {
8+
/**
9+
* Sample a single element from an array.
10+
*
11+
* @param {Array} a The input array.
12+
* @param {number} i Inclusive left bound.
13+
* @param {number} j Non-inclusive right bound.
14+
* @return {any} The sampled element.
15+
*/
16+
const choice = (a, i, j) => {
17+
const x = randint(i, j);
18+
return a[x];
19+
};
20+
21+
return choice;
22+
};
23+
24+
export default _choice;

test/src/choice.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import test from 'ava';
2+
import {choice, _choice, randint} from '../../src/index.js';
3+
4+
import {_calloc} from '@aureooms/js-memory';
5+
import {iota, copy} from '@aureooms/js-array';
6+
7+
const macro = (t, type, _, choice, n, i, j) => {
8+
const calloc = _calloc(type);
9+
const a = calloc(n);
10+
const b = calloc(n);
11+
12+
iota(a, 0, n, 0);
13+
copy(a, 0, n, b, 0);
14+
15+
const x = choice(b, i, j);
16+
17+
t.deepEqual(b, a);
18+
t.true(a.slice(i, j).includes(x));
19+
};
20+
21+
macro.title = (title, type, choice_name, _, n, i, j) =>
22+
title || `[${n}] choice ( ${type.name}, ${choice_name}, ${i}, ${j} )`;
23+
24+
const n = 100;
25+
const params = [
26+
[n, 0, n],
27+
[n, 20, n],
28+
[n, 0, n - 20],
29+
[n, 10, n - 10],
30+
];
31+
32+
const types = [
33+
Array,
34+
Int8Array,
35+
Int16Array,
36+
Int32Array,
37+
Uint8Array,
38+
Uint16Array,
39+
Uint32Array,
40+
Uint8ClampedArray,
41+
Float32Array,
42+
Float64Array,
43+
];
44+
45+
const algorithms = [
46+
['kernel', _choice(randint)],
47+
['API', choice],
48+
];
49+
50+
for (const type of types) {
51+
for (const [name, algorithm] of algorithms) {
52+
for (const [n, i, j] of params) {
53+
test(macro, type, name, algorithm, n, i, j);
54+
}
55+
}
56+
}

0 commit comments

Comments
 (0)