diff --git a/.changeset/nasty-suns-trade.md b/.changeset/nasty-suns-trade.md new file mode 100644 index 000000000..8b5e36282 --- /dev/null +++ b/.changeset/nasty-suns-trade.md @@ -0,0 +1,5 @@ +--- +"@modern-kit/utils": minor +--- + +feat(utils): findLastKey 함수 추가 - @Sangminnn diff --git a/docs/docs/utils/object/findLastKey.md b/docs/docs/utils/object/findLastKey.md new file mode 100644 index 000000000..afe24f2e8 --- /dev/null +++ b/docs/docs/utils/object/findLastKey.md @@ -0,0 +1,42 @@ +# findLastKey + +객체에서 조건에 부합하는 마지막 key를 반환합니다. + +## Code + +[🔗 실제 구현 코드 확인](https://github.com/modern-agile-team/modern-kit/blob/main/packages/utils/src/object/findLastKey/index.ts) + +## Benchmark + +- `hz`: 초당 작업 수 +- `mean`: 평균 응답 시간(ms) + +| 이름 | hz | mean | 성능 | +| ---------------------- | ------------- | ------ | ----------- | +| modern-kit/findLastKey | 19,157,255.73 | 0.0001 | `fastest` | +| lodash/findLastKey | 7,387,616.57 | 0.0001 | `slowest` | + +- **modern-kit/findLastKey** + - `2.59x` faster than lodash/findLastKey + +## Interface + +```ts +function findLastKey>( + obj: T, + condition: (value: T[keyof T) => boolean +): string | undefined +``` + +## Usage + +```ts +import { findLastKey } from '@modern-kit/utils'; + +const obj = { + bike: { active: true }, + car: { active: false }, + plane: { active: true }, +}; +findLastKey(obj, (item) => item.active); // 'plane' +``` diff --git a/packages/utils/src/object/findLastKey/findLastKey.bench.ts b/packages/utils/src/object/findLastKey/findLastKey.bench.ts new file mode 100644 index 000000000..13a89d84c --- /dev/null +++ b/packages/utils/src/object/findLastKey/findLastKey.bench.ts @@ -0,0 +1,19 @@ +import { bench, describe } from 'vitest'; +import { findLastKey } from '.'; +import { findLastKey as findLastKeyLodash } from 'lodash-es'; + +describe('findLastKey', () => { + const obj = { + bike: { active: true }, + car: { active: false }, + plane: { active: true }, + }; + + bench('modern-kit/findLastKey', () => { + findLastKey(obj, (item) => item.active); + }); + + bench('lodash/findLastKey', () => { + findLastKeyLodash(obj, (item) => item.active); + }); +}); diff --git a/packages/utils/src/object/findLastKey/findLastKey.spec.ts b/packages/utils/src/object/findLastKey/findLastKey.spec.ts new file mode 100644 index 000000000..decfe2a21 --- /dev/null +++ b/packages/utils/src/object/findLastKey/findLastKey.spec.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from 'vitest'; +import { findLastKey } from '.'; + +describe('findLastKey', () => { + it('should return correct key element when a existent key-value is accessed', () => { + const obj = { + bike: { active: true }, + car: { active: false }, + plane: { active: true }, + }; + + expect(findLastKey(obj, (item) => item.active)).toEqual('plane'); + }); + + it('should return undefined when a non-existent key-value is accessed', () => { + const obj = { + bike: { active: true }, + car: { active: false }, + plane: { active: true }, + }; + + expect(findLastKey(obj, (item) => (item as any).inactive)).toEqual( + undefined, + ); + }); +}); diff --git a/packages/utils/src/object/findLastKey/index.ts b/packages/utils/src/object/findLastKey/index.ts new file mode 100644 index 000000000..96268cc01 --- /dev/null +++ b/packages/utils/src/object/findLastKey/index.ts @@ -0,0 +1,33 @@ +/** + * @description 객체에서 조건에 부합하는 마지막 key를 반환합니다. + * + * @template T - 키를 찾고자 하는 객체 요소의 타입 + * @param {T} obj - 검색하고자 하는 객체입니다. + * @param {(value: T[keyof T]) => boolean} condition - 검색하고자 하는 조건입니다. + * @returns {string | undefined} 검색하고자 하는 조건에 부합하는 key를 반환합니다. 만약 조건에 부합하는 key가 없다면 undefined를 반환합니다. + * + * @example + * const obj = { + * bike: { active: true }, + * car: { active: false }, + * plane: { active: true }, + * }; + * + * findKey(obj, (item) => item.active); // 'plane' + */ +export function findLastKey>( + obj: T, + condition: (value: T[keyof T]) => boolean, +): string | undefined { + const keys = Object.keys(obj); + + for (let i = keys.length - 1; i >= 0; i--) { + const key = keys[i]; + const value = obj[key]; + + if (condition(value)) { + return key; + } + } + return undefined; +} diff --git a/packages/utils/src/object/index.ts b/packages/utils/src/object/index.ts index 60bd10483..8d29a8147 100644 --- a/packages/utils/src/object/index.ts +++ b/packages/utils/src/object/index.ts @@ -1,5 +1,6 @@ export * from './deleteFalsyProperties'; export * from './findKey'; +export * from './findLastKey'; export * from './groupBy'; export * from './invert'; export * from './mapKeys';