feat(invert): add invert (#125)

* feat: Add invert

* feat: Add test for invert

* feat: Add bench for invert

* docs: Add docs for invert

* docs: fix .vitepress for invert

* chore: Change incorrectly specified path

* chore: Refactor benchmark tests

* feat: refactor type invert

* Update src/object/invert.ts

---------

Co-authored-by: Sojin Park <raon0211@gmail.com>
This commit is contained in:
원동휘 2024-07-05 10:08:39 +09:00 committed by GitHub
parent 494519b2ce
commit 1918eec3d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 140 additions and 0 deletions

View File

@ -0,0 +1,18 @@
import { bench, describe } from 'vitest';
import { invert as invertByLodash } from 'lodash';
import { invert as invertByToolkit } from 'es-toolkit';
const object: { [key: string]: string } = {};
for (let i = 0; i < 10000; i++) {
object[`key${i}`] = `value${i}`;
}
describe('invert function benchmark', () => {
bench('es-toolkit/invert', () => {
invertByToolkit(object);
});
bench('lodash/invert', () => {
invertByLodash(object);
});
});

View File

@ -120,6 +120,7 @@ function sidebar(): DefaultTheme.Sidebar {
{ text: 'omitBy', link: '/reference/object/omitBy' },
{ text: 'pick', link: '/reference/object/pick' },
{ text: 'pickBy', link: '/reference/object/pickBy' },
{ text: 'invert', link: '/reference/object/invert' },
],
},
{

View File

@ -119,6 +119,7 @@ function sidebar(): DefaultTheme.Sidebar {
{ text: 'omitBy', link: '/ko/reference/object/omitBy' },
{ text: 'pick', link: '/ko/reference/object/pick' },
{ text: 'pickBy', link: '/ko/reference/object/pickBy' },
{ text: 'invert', link: '/ko/reference/object/invert' },
],
},
{

View File

@ -0,0 +1,29 @@
# invert
객체의 키와 값을 뒤집는 새로운 객체를 생성해요.
이 함수는 객체를 받아서 그 객체의 키를 값으로, 값을 키로 하는 새로운 객체를 생성해요. 만약 입력된 객체에 중복된 값이 있을 경우, 마지막에 등장한 키가 새로운 키로 사용돼요.
## 인터페이스
```typescript
function invert<K extends string | number | symbol, V extends string | number | symbol>(
obj: Record<K, V>
): { [key in V]: K };
```
### 파라미터
- `obj` (`Record<K, V>`): 키와 값을 뒤집을 객체예요.
### 반환 값
(`{ [key in V]: K }`): 키와 값이 뒤집힌 새로운 객체예요.
## 예시
```typescript
const obj = { a: 1, b: 1, c: 2 };
const result = invert(obj);
// 결과는 다음과 같아요 { 1: 'b', 2: 'c' }
```

View File

@ -0,0 +1,29 @@
# invert
Creates a new object by swapping the keys and values of the given object.
This function takes an object and creates a new object where the keys are the values and the values are the keys of the original object. If there are duplicate values in the input object, the key that appears last will be used as the new key.
## Signature
```typescript
function invert<K extends string | number | symbol, V extends string | number | symbol>(
obj: Record<K, V>
): { [key in V]: K };
```
### Parameters
- `obj` (`Record<K, V>`): The object to invert.
### Returns
(`{ [key in V]: K }`): A new object with keys and values inverted.
## Examples
```typescript
const obj = { a: 1, b: 1, c: 2 };
const result = invert(obj);
// result will be { 1: 'b', 2: 'c' }
```

View File

@ -2,3 +2,4 @@ export { omit } from './omit.ts';
export { omitBy } from './omitBy.ts';
export { pick } from './pick.ts';
export { pickBy } from './pickBy.ts';
export { invert } from './invert.ts';

30
src/object/invert.spec.ts Normal file
View File

@ -0,0 +1,30 @@
import { describe, it, expect } from 'vitest';
import { invert } from './invert';
describe('invert', () => {
it('should invert a simple object with string keys and number values', () => {
expect(invert({ a: 1, b: 2, c: 3 })).toEqual({ 1: 'a', 2: 'b', 3: 'c' });
});
it('should invert an object with number keys and string values', () => {
expect(invert({ 1: 'a', 2: 'b', 3: 'c' })).toEqual({ a: '1', b: '2', c: '3' });
});
it('should handle an object with mixed key and value types', () => {
expect(invert({ a: 1, 2: 'b', c: 3, 4: 'd' })).toEqual({ 1: 'a', b: '2', 3: 'c', d: '4' });
});
it('should handle an object with symbol keys', () => {
const sym1 = Symbol('sym1');
const sym2 = Symbol('sym2');
expect(invert({ a: sym1, b: sym2 })).toEqual({ [sym1]: 'a', [sym2]: 'b' });
});
it('should handle an empty object', () => {
expect(invert({})).toEqual({});
});
it('should handle objects with duplicate values by keeping the last key', () => {
expect(invert({ a: 1, b: 1, c: 2 })).toEqual({ 1: 'b', 2: 'c' });
});
});

31
src/object/invert.ts Normal file
View File

@ -0,0 +1,31 @@
/**
* Inverts the keys and values of an object. The keys of the input object become the values of the output object and vice versa.
*
* This function takes an object and creates a new object by inverting its keys and values. If the input object has duplicate values,
* the key of the last occurrence will be used as the value for the new key in the output object. It effectively creates a reverse mapping
* of the input object's key-value pairs.
*
* @template K - Type of the keys in the input object (string, number, symbol)
* @template V - Type of the values in the input object (string, number, symbol)
* @param {Record<K, V>} obj - The input object whose keys and values are to be inverted
* @returns {{ [key in V]: K }} - A new object with keys and values inverted
*
* @example
* invert({ a: 1, b: 2, c: 3 }); // { 1: 'a', 2: 'b', 3: 'c' }
* invert({ 1: 'a', 2: 'b', 3: 'c' }); // { a: '1', b: '2', c: '3' }
* invert({ a: 1, 2: 'b', c: 3, 4: 'd' }); // { 1: 'a', b: '2', 3: 'c', d: '4' }
* invert({ a: Symbol('sym1'), b: Symbol('sym2') }); // { [Symbol('sym1')]: 'a', [Symbol('sym2')]: 'b' }
*/
type PropertyKey = string | number | symbol;
export function invert<K extends PropertyKey, V extends PropertyKey>(obj: Record<K, V>): { [key in V]: K } {
const result = {} as { [key in V]: K };
for (const key in obj) {
const value = obj[key as K] as V;
result[value] = key;
}
return result;
}