From 415d325ff0d085fa8a977a96cced420a82c4adf2 Mon Sep 17 00:00:00 2001 From: hyunwoo Date: Thu, 24 Oct 2024 13:51:24 +0900 Subject: [PATCH] feat(uniqueId): Add uniqueId to compat layer (#714) * feat(uniqueId): Add uniqueId to compat layer * refactor: changed the implementation of uniqueId to improve readability. * feat: use lodash's test code * test: add test case * Update docs --------- Co-authored-by: raon0211 --- benchmarks/performance/uniqueId.bench.ts | 31 +++++++++++++++++++ docs/ja/reference/compat/util/uniqueId.md | 30 ++++++++++++++++++ docs/ko/reference/compat/util/uniqueId.md | 30 ++++++++++++++++++ docs/reference/compat/util/uniqueId.md | 30 ++++++++++++++++++ .../zh_hans/reference/compat/util/uniqueId.md | 30 ++++++++++++++++++ src/compat/index.ts | 1 + src/compat/util/uniqueId.spec.ts | 23 ++++++++++++++ src/compat/util/uniqueId.ts | 30 ++++++++++++++++++ 8 files changed, 205 insertions(+) create mode 100644 benchmarks/performance/uniqueId.bench.ts create mode 100644 docs/ja/reference/compat/util/uniqueId.md create mode 100644 docs/ko/reference/compat/util/uniqueId.md create mode 100644 docs/reference/compat/util/uniqueId.md create mode 100644 docs/zh_hans/reference/compat/util/uniqueId.md create mode 100644 src/compat/util/uniqueId.spec.ts create mode 100644 src/compat/util/uniqueId.ts diff --git a/benchmarks/performance/uniqueId.bench.ts b/benchmarks/performance/uniqueId.bench.ts new file mode 100644 index 00000000..8a380172 --- /dev/null +++ b/benchmarks/performance/uniqueId.bench.ts @@ -0,0 +1,31 @@ +import { bench, describe } from 'vitest'; +import { uniqueId as uniqueIdToolkitCompat } from 'es-toolkit/compat'; +import { uniqueId as uniqueIdLodash } from 'lodash'; + +describe('uniqueId', () => { + bench('es-toolkit/compat/uniqueId', () => { + uniqueIdToolkitCompat(); + uniqueIdToolkitCompat(); + uniqueIdToolkitCompat(); + uniqueIdToolkitCompat(); + uniqueIdToolkitCompat(); + uniqueIdToolkitCompat('prefix_'); + uniqueIdToolkitCompat('prefix_'); + uniqueIdToolkitCompat('prefix_'); + uniqueIdToolkitCompat('prefix_'); + uniqueIdToolkitCompat('prefix_'); + }); + + bench('lodash/uniqueId', () => { + uniqueIdLodash(); + uniqueIdLodash(); + uniqueIdLodash(); + uniqueIdLodash(); + uniqueIdLodash(); + uniqueIdLodash('prefix_'); + uniqueIdLodash('prefix_'); + uniqueIdLodash('prefix_'); + uniqueIdLodash('prefix_'); + uniqueIdLodash('prefix_'); + }); +}); diff --git a/docs/ja/reference/compat/util/uniqueId.md b/docs/ja/reference/compat/util/uniqueId.md new file mode 100644 index 00000000..138f69a4 --- /dev/null +++ b/docs/ja/reference/compat/util/uniqueId.md @@ -0,0 +1,30 @@ +# uniqueId + +::: info +この関数は互換性のために `es-toolkit/compat` からのみインポートできます。代替可能なネイティブ JavaScript API があるか、まだ十分に最適化されていないためです。 + +`es-toolkit/compat` からこの関数をインポートすると、[lodash と完全に同じように動作](../../../compatibility.md)します。 +::: + +一意の文字列識別子を生成します。オプションで、先頭に付ける接頭辞文字列を指定できます。 + +## インターフェース + +```typescript +function uniqueId(prefix?: string): string; +``` + +### パラメータ + +- `prefix` (`string`, optional): 識別子の先頭に付ける値。 + +### 戻り値 + +(`string`): 一意の識別子。 + +## 例 + +```typescript +uniqueId('contact_'); // => 'contact_104' +uniqueId(); // => '105' +``` diff --git a/docs/ko/reference/compat/util/uniqueId.md b/docs/ko/reference/compat/util/uniqueId.md new file mode 100644 index 00000000..0ee233d4 --- /dev/null +++ b/docs/ko/reference/compat/util/uniqueId.md @@ -0,0 +1,30 @@ +# uniqueId + +::: info +이 함수는 호환성을 위한 `es-toolkit/compat` 에서만 가져올 수 있어요. 대체할 수 있는 네이티브 JavaScript API가 있거나, 아직 충분히 최적화되지 않았기 때문이에요. + +`es-toolkit/compat`에서 이 함수를 가져오면, [lodash와 완전히 똑같이 동작](../../../compatibility.md)해요. +::: + +고유한 문자열 식별자를 생성해요. 앞에 붙일 접두사 문자열를 선택적으로 지정할 수 있어요. + +## 인터페이스 + +```typescript +function uniqueId(prefix?: string): string; +``` + +### 파라미터 + +- `prefix` (`string`, optional): ID 앞에 붙는 접두사 문자열. + +### 반환 값 + +(`string`): 고유 식별자 문자열. + +## 예시 + +```typescript +uniqueId('contact_'); // => 'contact_104' +uniqueId(); // => '105' +``` diff --git a/docs/reference/compat/util/uniqueId.md b/docs/reference/compat/util/uniqueId.md new file mode 100644 index 00000000..52848eec --- /dev/null +++ b/docs/reference/compat/util/uniqueId.md @@ -0,0 +1,30 @@ +# constant + +::: info +This function is only available in `es-toolkit/compat` for compatibility reasons. It either has alternative native JavaScript APIs or isn’t fully optimized yet. + +When imported from `es-toolkit/compat`, it behaves exactly like lodash and provides the same functionalities, as detailed [here](../../../compatibility.md). +::: + +Generates a unique identifier, optionally prefixed with a given string. + +## Signature + +```typescript +function uniqueId(prefix?: string): string; +``` + +### Parameters + +- `prefix` (`string`, optional): The value to prefix the ID with. + +### Returns + +(`string`): Returns the unique ID. + +## Examples + +```typescript +uniqueId('contact_'); // => 'contact_104' +uniqueId(); // => '105' +``` diff --git a/docs/zh_hans/reference/compat/util/uniqueId.md b/docs/zh_hans/reference/compat/util/uniqueId.md new file mode 100644 index 00000000..df776bbe --- /dev/null +++ b/docs/zh_hans/reference/compat/util/uniqueId.md @@ -0,0 +1,30 @@ +# toString + +::: info +出于兼容性原因,此函数仅在 `es-toolkit/compat` 中提供。它可能具有替代的原生 JavaScript API,或者尚未完全优化。 + +从 `es-toolkit/compat` 导入时,它的行为与 lodash 完全一致,并提供相同的功能,详情请见 [这里](../../../compatibility.md)。 +::: + +生成一个唯一的标识符,可选地以给定字符串作为前缀。 + +## 签名 + +```typescript +function uniqueId(prefix?: string): string; +``` + +### 参数 + +- `prefix` (`string`, optional): 标识符的前缀值。 + +### 返回值 + +(`string`): 返回唯一标识符。 + +## 示例 + +```typescript +uniqueId('contact_'); // => 'contact_104' +uniqueId(); // => '105' +``` diff --git a/src/compat/index.ts b/src/compat/index.ts index 478e6831..fb5b0503 100644 --- a/src/compat/index.ts +++ b/src/compat/index.ts @@ -168,3 +168,4 @@ export { toNumber } from './util/toNumber.ts'; export { toPath } from './util/toPath.ts'; export { toSafeInteger } from './util/toSafeInteger.ts'; export { toString } from './util/toString.ts'; +export { uniqueId } from './util/uniqueId.ts'; diff --git a/src/compat/util/uniqueId.spec.ts b/src/compat/util/uniqueId.spec.ts new file mode 100644 index 00000000..516fc4d2 --- /dev/null +++ b/src/compat/util/uniqueId.spec.ts @@ -0,0 +1,23 @@ +import { describe, expect, it } from 'vitest'; +import { uniqueId } from './uniqueId'; + +describe('uniqueId', () => { + it('should generate unique ids', () => { + const actual = Array.from({ length: 1000 }, () => uniqueId()); + + expect(new Set(actual).size).toBe(actual.length); + }); + + it('should return a string value when not providing a `prefix`', () => { + expect(typeof uniqueId()).toBe('string'); + }); + + it('should coerce the prefix argument to a string', () => { + // @ts-expect-error + const ids = [uniqueId(3), uniqueId(2), uniqueId(1), uniqueId(true)]; + expect(ids[0].startsWith('3')).toBe(true); + expect(ids[1].startsWith('2')).toBe(true); + expect(ids[2].startsWith('1')).toBe(true); + expect(ids[3].startsWith('true')).toBe(true); + }); +}); diff --git a/src/compat/util/uniqueId.ts b/src/compat/util/uniqueId.ts new file mode 100644 index 00000000..a680dc9b --- /dev/null +++ b/src/compat/util/uniqueId.ts @@ -0,0 +1,30 @@ +/** Counter used to generate unique numeric identifiers. */ +let idCounter = 0; + +/** + * Generates a unique identifier, optionally prefixed with a given string. + * + * @param {string} [prefix] - An optional string to prefix the unique identifier. + * If not provided or not a string, only the unique + * numeric identifier is returned. + * @returns {string} A string containing the unique identifier, with the optional + * prefix if provided. + * + * @example + * // Generate a unique ID with a prefix + * uniqueId('user_'); // => 'user_1' + * + * @example + * // Generate a unique ID without a prefix + * uniqueId(); // => '2' + * + * @example + * // Subsequent calls increment the internal counter + * uniqueId('item_'); // => 'item_3' + * uniqueId(); // => '4' + */ +export function uniqueId(prefix = ''): string { + const id = ++idCounter; + + return `${prefix}${id}`; +}