mirror of
https://github.com/toss/es-toolkit.git
synced 2024-11-27 14:57:44 +03:00
feat(sampleSize): Add sampleSize (#101)
This commit is contained in:
parent
6c9c0d1c26
commit
02f14b3697
15
benchmarks/sampleSize.bench.ts
Normal file
15
benchmarks/sampleSize.bench.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { bench, describe } from 'vitest';
|
||||
import { sampleSize as sampleSizeToolkit } from 'es-toolkit';
|
||||
import { sampleSize as sampleSizeLodash } from 'lodash';
|
||||
|
||||
describe('sampleSize', () => {
|
||||
bench('es-toolkit/sampleSize', () => {
|
||||
const array = [1, 2, 3, 4, 5];
|
||||
sampleSizeToolkit(array, 3);
|
||||
});
|
||||
|
||||
bench('lodash/sampleSize', () => {
|
||||
const array = [1, 2, 3, 4, 5];
|
||||
sampleSizeLodash(array, 3);
|
||||
});
|
||||
});
|
@ -65,6 +65,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'maxBy', link: '/reference/array/maxBy' },
|
||||
{ text: 'partition', link: '/reference/array/partition' },
|
||||
{ text: 'sample', link: '/reference/array/sample' },
|
||||
{ text: 'sampleSize', link: '/reference/array/sampleSize' },
|
||||
{ text: 'shuffle', link: '/reference/array/shuffle' },
|
||||
{ text: 'take', link: '/reference/array/take' },
|
||||
{ text: 'takeWhile', link: '/reference/array/takeWhile' },
|
||||
|
@ -64,6 +64,7 @@ function sidebar(): DefaultTheme.Sidebar {
|
||||
{ text: 'maxBy', link: '/ko/reference/array/maxBy' },
|
||||
{ text: 'partition', link: '/ko/reference/array/partition' },
|
||||
{ text: 'sample', link: '/ko/reference/array/sample' },
|
||||
{ text: 'sampleSize', link: '/ko/reference/array/sampleSize' },
|
||||
{ text: 'shuffle', link: '/ko/reference/array/shuffle' },
|
||||
{ text: 'take', link: '/ko/reference/array/take' },
|
||||
{ text: 'takeWhile', link: '/ko/reference/array/takeWhile' },
|
||||
|
32
docs/ko/reference/array/sampleSize.md
Normal file
32
docs/ko/reference/array/sampleSize.md
Normal file
@ -0,0 +1,32 @@
|
||||
# sampleSize
|
||||
|
||||
지정된 `size`의 샘플 요소 배열을 반환해요.
|
||||
|
||||
이 함수는 배열과 숫자를 받아요. [Floyd의 알고리즘](https://www.nowherenearithaca.com/2013/05/robert-floyds-tiny-and-beautiful.html)을 사용해서 샘플된 요소들이 포함된 배열을 반환해요.
|
||||
|
||||
## 인터페이스
|
||||
|
||||
```typescript
|
||||
export function sampleSize<T>(array: readonly T[], size: number): T[];
|
||||
```
|
||||
|
||||
### 파리미터
|
||||
|
||||
- `array` (`T[]`): 샘플링할 배열이에요.
|
||||
- `size` (`number`): 샘플링할 크기에요.
|
||||
|
||||
### 반환 값
|
||||
|
||||
(`T[]`): 샘플 크기가 적용된 새로운 배열이에요.
|
||||
|
||||
### 에러
|
||||
|
||||
`size`가 `array`의 길이보다 크면 에러를 던져요.
|
||||
|
||||
## 예시
|
||||
|
||||
```typescript
|
||||
const result = sampleSize([1, 2, 3], 2);
|
||||
// 결과는 배열의 요소 중 두 개를 포함하는 배열이 돼요.
|
||||
// [1, 2] or [1, 3] or [2, 3]
|
||||
```
|
32
docs/reference/array/sampleSize.md
Normal file
32
docs/reference/array/sampleSize.md
Normal file
@ -0,0 +1,32 @@
|
||||
# sampleSize
|
||||
|
||||
Returns a sample element array of a specified `size`.
|
||||
|
||||
This function takes an array and a number, and returns an array containing the sampled elements using [Floyd's algorithm](https://www.nowherenearithaca.com/2013/05/robert-floyds-tiny-and-beautiful.html).
|
||||
|
||||
## Signature
|
||||
|
||||
```typescript
|
||||
export function sampleSize<T>(array: readonly T[], size: number): T[];
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- `array` (`T[]`): The array to sample from.
|
||||
- `size` (`number`): The size of sample.
|
||||
|
||||
### Returns
|
||||
|
||||
(`T[]`): A new array with sample size applied.
|
||||
|
||||
### Throws
|
||||
|
||||
Throws an error if `size` is greater than the length of `array`.
|
||||
|
||||
## Examples
|
||||
|
||||
```typescript
|
||||
const result = sampleSize([1, 2, 3], 2);
|
||||
// result will be an array containing two of the elements from the array.
|
||||
// [1, 2] or [1, 3] or [2, 3]
|
||||
```
|
@ -16,6 +16,7 @@ export { maxBy } from './maxBy.ts';
|
||||
export { minBy } from './minBy.ts';
|
||||
export { partition } from './partition.ts';
|
||||
export { sample } from './sample.ts';
|
||||
export { sampleSize } from './sampleSize.ts';
|
||||
export { shuffle } from './shuffle.ts';
|
||||
export { take } from './take.ts';
|
||||
export { takeRight } from './takeRight.ts';
|
||||
|
30
src/array/sampleSize.spec.ts
Normal file
30
src/array/sampleSize.spec.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { sampleSize } from './sampleSize';
|
||||
|
||||
describe('sampleSize', () => {
|
||||
it('returns a sample element array of a specified size', () => {
|
||||
const array = [1, 2, 3];
|
||||
const result = sampleSize(array, 2);
|
||||
|
||||
expect(array).toEqual(expect.arrayContaining(result));
|
||||
});
|
||||
|
||||
it('returns an empty array for size 0', () => {
|
||||
const result = sampleSize([1, 2, 3], 0);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('returns the same array if the size is equal to the array length', () => {
|
||||
const array = [1, 2, 3];
|
||||
const result = sampleSize(array, array.length);
|
||||
|
||||
expect(result).toEqual(array);
|
||||
expect(result).not.toBe(array);
|
||||
});
|
||||
|
||||
it('throws an error if the size is greater than the array length', () => {
|
||||
expect(() => sampleSize([1, 2, 3], 4)).toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Size must be less than or equal to the length of array.]`
|
||||
);
|
||||
});
|
||||
});
|
41
src/array/sampleSize.ts
Normal file
41
src/array/sampleSize.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { randomInt } from '../math';
|
||||
|
||||
/**
|
||||
* Returns a sample element array of a specified `size`.
|
||||
*
|
||||
* This function takes an array and a number, and returns an array containing the sampled elements using Floyd's algorithm.
|
||||
*
|
||||
* {@link https://www.nowherenearithaca.com/2013/05/robert-floyds-tiny-and-beautiful.html Floyd's algoritm}
|
||||
*
|
||||
* @param {T[]} array - The array to sample from.
|
||||
* @param {number} size - The size of sample.
|
||||
* @returns {T[]} A new array with sample size applied.
|
||||
* @throws {Error} Throws an error if `size` is greater than the length of `array`.
|
||||
*
|
||||
* @example
|
||||
* const result = sampleSize([1, 2, 3], 2)
|
||||
* // result will be an array containing two of the elements from the array.
|
||||
* // [1, 2] or [1, 3] or [2, 3]
|
||||
*/
|
||||
export function sampleSize<T>(array: readonly T[], size: number): T[] {
|
||||
if (size > array.length) {
|
||||
throw new Error('Size must be less than or equal to the length of array.');
|
||||
}
|
||||
|
||||
const result = new Array(size);
|
||||
const selected = new Set();
|
||||
|
||||
for (let step = array.length - size, resultIndex = 0; step < array.length; step++, resultIndex++) {
|
||||
let index = randomInt(0, step + 1);
|
||||
|
||||
if (selected.has(index)) {
|
||||
index = step;
|
||||
}
|
||||
|
||||
selected.add(index);
|
||||
|
||||
result[resultIndex] = array[index];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Reference in New Issue
Block a user