Skip to content

Commit

Permalink
feat(map): implement map
Browse files Browse the repository at this point in the history
  • Loading branch information
D-Sketon committed Dec 1, 2024
1 parent 66575a9 commit aadd727
Show file tree
Hide file tree
Showing 8 changed files with 600 additions and 0 deletions.
63 changes: 63 additions & 0 deletions benchmarks/performance/map.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { bench, describe } from 'vitest';
import { map as mapToolkit_ } from 'es-toolkit/compat';
import { map as mapLodash_ } from 'lodash';

const mapToolkit = mapToolkit_;
const mapLodash = mapLodash_;

const generateArray = (length: number) => Array.from({ length }, (_, i) => i);
const generateObject = (length: number) => Object.fromEntries(generateArray(length).map(i => [`key${i}`, i]));

describe('map/array', () => {
const array = [1, 2, 3, 4, 5];

bench('es-toolkit/map', () => {
mapToolkit(array, value => value * 2);
});

bench('lodash/map', () => {
mapLodash(array, value => value * 2);
});
});

describe('map/object', () => {
const obj = {
key1: 1,
key2: 2,
key3: 3,
key4: 4,
key5: 5,
};

bench('es-toolkit/map', () => {
mapToolkit(obj, value => value * 2);
});

bench('lodash/map', () => {
mapLodash(obj, value => value * 2);
});
});

describe('map/largeArray', () => {
const largeArray = generateArray(10000);

bench('es-toolkit/map', () => {
mapToolkit(largeArray, value => value * 2);
});

bench('lodash/map', () => {
mapLodash(largeArray, value => value * 2);
});
});

describe('map/largeObject', () => {
const largeObject = generateObject(10000);

bench('es-toolkit/map', () => {
mapToolkit(largeObject, value => value * 2);
});

bench('lodash/map', () => {
mapLodash(largeObject, value => value * 2);
});
});
65 changes: 65 additions & 0 deletions docs/ja/reference/compat/array/map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# map

::: info
この関数は互換性のために `es-toolkit/compat` からのみインポートできます。代替可能なネイティブ JavaScript API があるか、まだ十分に最適化されていないためです。

`es-toolkit/compat` からこの関数をインポートすると、[lodash と完全に同じように動作](../../../compatibility.md)します。
:::

提供されたイテレータに基づいて変換された値の新しい配列を返します。

イテレータは次のように指定できます:

- **変換関数**:変換関数を提供すると、各要素に適用されます。
- **プロパティキー**:プロパティキーを提供すると、関数は各要素から指定されたプロパティの値を返します。
- **オブジェクト**:オブジェクトを提供すると、関数は各要素をオブジェクトと比較し、一致する場合は `true` を返します。

## シグネチャ

```typescript
function map<T, U>(collection: T[], iteratee: (value: T, index: number, collection: T[]) => U): U[];
function map<T, U>(collection: ArrayLike<T>, iteratee: (value: T, index: number, collection: ArrayLike<T>) => U): U[];
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: null | undefined): T[];
function map<T extends object, U>(collection: T, iteratee: (value: T[keyof T], key: string, collection: T) => U): U[];
function map<T, K extends keyof T>(collection: Record<string, T> | Record<number, T>, iteratee: K): Array<T[K]>;
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: string): any[];
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: object): boolean[];
```

### パラメータ

- `collection` (`T[]` | `ArrayLike<T>` | `Record<string, T>` | `Record<number, T>`): イテレーションするコレクション。

- `iteratee`:

- **変換関数** (`(value: T, index: number, collection: T[]) => U`): 各要素を変換する関数。
- **プロパティキー** (`K` | `string`): 各要素から抽出するプロパティのキー。
- **オブジェクト** (`object`): 各要素と比較するオブジェクト。

### 戻り値

(`any[]`): 変換された値の新しい配列。

## 使用例

```typescript
// 変換関数使用
const array = [1, 2, 3];
map(array, value => value * 2); // => [2, 4, 6]

// イテレータでプロパティキーを使用
const objects = [{ a: 1 }, { a: 2 }, { a: 3 }];
map(objects, 'a'); // => [1, 2, 3]

// イテレータでオブジェクトを使用
const objects = [{ a: 1 }, { a: 2 }, { a: 3 }];
map(objects, { a: 1 }); // => [true, false, false]

// イテレータなし
const numbers = [1, 2, 3];
map(numbers); // => [1, 2, 3]

// オブジェクトでコレクションを使用
const obj = { a: 1, b: 2, c: 3 };
map(obj, (value, key) => `${key}: ${value}`); // => ['a: 1', 'b: 2', 'c: 3']
```
65 changes: 65 additions & 0 deletions docs/ko/reference/compat/array/map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# map

::: info
이 함수는 호환성을 위한 `es-toolkit/compat` 에서만 가져올 수 있어요. 대체할 수 있는 네이티브 JavaScript API가 있거나, 아직 충분히 최적화되지 않았기 때문이에요.

`es-toolkit/compat`에서 이 함수를 가져오면, [lodash와 완전히 똑같이 동작](../../../compatibility.md)해요.
:::

배열의 각 요소에 대해 제공된 이터레이터를 기반으로 변환된 값의 새 배열을 반환해요.

이터레이터는 다음과 같은 방법으로 지정할 수 있어요:

- **변환 함수**: 변환 함수를 제공하면 각 요소에 적용돼요.
- **속성 키**: 속성 키를 제공하면 함수는 각 요소에서 지정된 속성의 값을 반환해요.
- **객체**: 객체를 제공하면 함수는 각 요소를 객체와 비교하고 일치하는 경우 `true`를 반환해요.

## 인터페이스

```typescript
function map<T, U>(collection: T[], iteratee: (value: T, index: number, collection: T[]) => U): U[];
function map<T, U>(collection: ArrayLike<T>, iteratee: (value: T, index: number, collection: ArrayLike<T>) => U): U[];
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: null | undefined): T[];
function map<T extends object, U>(collection: T, iteratee: (value: T[keyof T], key: string, collection: T) => U): U[];
function map<T, K extends keyof T>(collection: Record<string, T> | Record<number, T>, iteratee: K): Array<T[K]>;
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: string): any[];
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: object): boolean[];
```

### 파라미터

- `collection` (`T[]` | `ArrayLike<T>` | `Record<string, T>` | `Record<number, T>`): 이터레이션할 컬렉션입니다.

- `iteratee`:

- **변환 함수** (`(value: T, index: number, collection: T[]) => U`): 각 요소를 변환하는 함수입니다.
- **속성 키** (`K` | `string`): 각 요소에서 추출할 속성의 키입니다.
- **객체** (`object`): 각 요소를 비교할 객체입니다.

### 반환 값

(`any[]`): 변환된 값의 새 배열입니다.

### 예시

```typescript
// 변환 함수 사용
const array = [1, 2, 3];
map(array, value => value * 2); // => [2, 4, 6]

// 이터레이터로 속성 키 사용
const objects = [{ a: 1 }, { a: 2 }, { a: 3 }];
map(objects, 'a'); // => [1, 2, 3]

// 이터레이터로 객체 사용
const objects = [{ a: 1 }, { a: 2 }, { a: 3 }];
map(objects, { a: 1 }); // => [true, false, false]

// 이터레이터 없음
const numbers = [1, 2, 3];
map(numbers); // => [1, 2, 3]

// 객체로 컬렉션 사용
const obj = { a: 1, b: 2, c: 3 };
map(obj, (value, key) => `${key}: ${value}`); // => ['a: 1', 'b: 2', 'c: 3']
```
65 changes: 65 additions & 0 deletions docs/reference/compat/array/map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# map

::: 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).
:::

Returns a new array of transformed values based on the provided iteratee.

The iteratee can be specified in several ways:

- **Transformation function**: If you provide a transformation function, the function will be applied to each element.
- **Property key**: If you provide a property key, the function will return the value of the specified property from each element.
- **Object**: If you provide an object, the function will use `isEqual` to compare each element to the object and return `true` if they match.

## Signature

```typescript
function map<T, U>(collection: T[], iteratee: (value: T, index: number, collection: T[]) => U): U[];
function map<T, U>(collection: ArrayLike<T>, iteratee: (value: T, index: number, collection: ArrayLike<T>) => U): U[];
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: null | undefined): T[];
function map<T extends object, U>(collection: T, iteratee: (value: T[keyof T], key: string, collection: T) => U): U[];
function map<T, K extends keyof T>(collection: Record<string, T> | Record<number, T>, iteratee: K): Array<T[K]>;
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: string): any[];
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: object): boolean[];
```

### Parameters

- `collection` (`T[]` | `ArrayLike<T>` | `Record<string, T>` | `Record<number, T>`): The collection to iterate over.

- `iteratee`:

- **Transformation function** (`(value: T, index: number, collection: T[]) => U`): A function that transforms each element.
- **Property key** (`K` | `string`): The key of the property to extract from each element.
- **Object** (`object`): An object to compare each element to.

### Returns

(`any[]`): A new array of transformed values.

### Example

```typescript
// Using a transformation function
const array = [1, 2, 3];
map(array, value => value * 2); // => [2, 4, 6]

// Using a property key as the iteratee
const objects = [{ a: 1 }, { a: 2 }, { a: 3 }];
map(objects, 'a'); // => [1, 2, 3]

// Using an object as the iteratee
const objects = [{ a: 1 }, { a: 2 }, { a: 3 }];
map(objects, { a: 1 }); // => [true, false, false]

// No iteratee
const numbers = [1, 2, 3];
map(numbers); // => [1, 2, 3]

// Using an object as the collection
const obj = { a: 1, b: 2, c: 3 };
map(obj, (value, key) => `${key}: ${value}`); // => ['a: 1', 'b: 2', 'c: 3']
```
65 changes: 65 additions & 0 deletions docs/zh_hans/reference/compat/array/map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# map

::: info
出于兼容性原因,此函数仅在 `es-toolkit/compat` 中提供。它可能具有替代的原生 JavaScript API,或者尚未完全优化。

`es-toolkit/compat` 导入时,它的行为与 lodash 完全一致,并提供相同的功能,详情请见 [这里](../../../compatibility.md)
:::

返回基于提供的迭代器的转换值的新数组。

迭代器可以通过以下几种方式指定:

- **转换函数**:如果提供了转换函数,将对每个元素应用该函数。
- **属性键**:如果提供了属性键,函数将从每个元素中返回指定属性的值。
- **对象**:如果提供了对象,函数将使用 `isEqual` 比较每个元素与对象,并在它们匹配时返回 `true`

## 签名

```typescript
function map<T, U>(collection: T[], iteratee: (value: T, index: number, collection: T[]) => U): U[];
function map<T, U>(collection: ArrayLike<T>, iteratee: (value: T, index: number, collection: ArrayLike<T>) => U): U[];
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: null | undefined): T[];
function map<T extends object, U>(collection: T, iteratee: (value: T[keyof T], key: string, collection: T) => U): U[];
function map<T, K extends keyof T>(collection: Record<string, T> | Record<number, T>, iteratee: K): Array<T[K]>;
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: string): any[];
function map<T>(collection: Record<string, T> | Record<number, T>, iteratee?: object): boolean[];
```

### 参数

- `collection` (`T[]` | `ArrayLike<T>` | `Record<string, T>` | `Record<number, T>`): 要迭代的集合。

- `iteratee`:

- **转换函数** (`(value: T, index: number, collection: T[]) => U`): 一个将每个元素转换的函数。
- **属性键** (`K` | `string`): 要从每个元素中提取的属性的键。
- **对象** (`object`): 要将每个元素与之比较的对象。

### 返回

(`any[]`): 一个新的转换值数组。

### 示例

```typescript
// 使用转换函数
const array = [1, 2, 3];
map(array, value => value * 2); // => [2, 4, 6]

// 使用属性键作为迭代器
const objects = [{ a: 1 }, { a: 2 }, { a: 3 }];
map(objects, 'a'); // => [1, 2, 3]

// 使用对象作为迭代器
const objects = [{ a: 1 }, { a: 2 }, { a: 3 }];
map(objects, { a: 1 }); // => [true, false, false]

// 没有迭代器
const numbers = [1, 2, 3];
map(numbers); // => [1, 2, 3]

// 使用对象作为集合
const obj = { a: 1, b: 2, c: 3 };
map(obj, (value, key) => `${key}: ${value}`); // => ['a: 1', 'b: 2', 'c: 3']
```
Loading

0 comments on commit aadd727

Please sign in to comment.