Skip to content

Commit

Permalink
feat(nth): add nth to compat (#865)
Browse files Browse the repository at this point in the history
  • Loading branch information
mass2527 authored Dec 4, 2024
1 parent c93ff84 commit f7abb57
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 2 deletions.
34 changes: 34 additions & 0 deletions benchmarks/performance/nth.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { bench, describe } from 'vitest';
import { nth as nthToolkitCompat_ } from 'es-toolkit/compat';
import { nth as nthLodash_ } from 'lodash';

const nthToolkitCompat = nthToolkitCompat_;
const nthLodash = nthLodash_;

describe('nth', () => {
const array = [1, 2, 3];

bench('es-toolkit/compat/nth', () => {
nthToolkitCompat(array, 1);
nthToolkitCompat(array, -1);
});

bench('lodash/nth', () => {
nthLodash(array, 1);
nthLodash(array, -1);
});
});

describe('nth/largeArray', () => {
const largeArray = Array.from({ length: 10000 }, (_, i) => i);

bench('es-toolkit/compat/nth', () => {
nthToolkitCompat(largeArray, 1);
nthToolkitCompat(largeArray, -1);
});

bench('lodash/nth', () => {
nthLodash(largeArray, 1);
nthLodash(largeArray, -1);
});
});
31 changes: 31 additions & 0 deletions docs/ja/reference/compat/array/nth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# nth

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

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

`array`のインデックス`n`にある要素を取得します。 `n`が負の場合、最後からn番目の要素が返されます。

## インターフェース

```typescript
function nth<T>(array: ArrayLike<T> | null | undefined, n: number): T | undefined;
```

### パラメータ

- `array` (`ArrayLike<T> | null | undefined`): 照会する配列。数値配列。
- `n` (`number`): 返す要素のインデックス。数値。

### 戻り値

(`T | undefined`): `array`のn番目の要素を返します。

##

```typescript
nth([1, 2, 3], 1); // => 2
nth([1, 2, 3], -1); // => 3
```
31 changes: 31 additions & 0 deletions docs/ko/reference/compat/array/nth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# nth

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

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

배열에서 인덱스 `n`에 해당하는 요소를 가져와요. `n`이 음수라면 끝에서부터 계산된 요소를 반환해요.

## 인터페이스

```typescript
function nth<T>(array: ArrayLike<T> | null | undefined, n: number): T | undefined;
```

### 파라미터

- `array` (`ArrayLike<T> | null | undefined`): 조회할 배열.
- `n` (`number`): 반환할 요소의 인덱스.

### 반환 값

(`T | undefined`): `array`의 n번째 요소.

## 예시

```typescript
nth([1, 2, 3], 1); // => 2
nth([1, 2, 3], -1); // => 3
```
31 changes: 31 additions & 0 deletions docs/reference/compat/array/nth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# nth

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

Gets the element at index `n` of `array`. If `n` is negative, the nth element from the end is returned.

## Signature

```typescript
function nth<T>(array: ArrayLike<T> | null | undefined, n: number): T | undefined;
```

### Parameters

- `array` (`ArrayLike<T> | null | undefined`): The array to query.
- `n` (`number`): The index of the element to return.

### Returns

(`T | undefined`): Returns the nth element of `array`.

## Examples

```typescript
nth([1, 2, 3], 1); // => 2
nth([1, 2, 3], -1); // => 3
```
31 changes: 31 additions & 0 deletions docs/zh_hans/reference/compat/array/nth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# nth

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

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

获取数组中索引为 `n` 的元素。如果 `n` 为负数,则返回倒数第 n 个元素。

## 签名

```typescript
function nth<T>(array: ArrayLike<T> | null | undefined, n: number): T | undefined;
```

### 参数

- `array` (`ArrayLike<T> | null | undefined`): 要查询的数组。
- `n` (`number`): 要返回的元素的索引。

### 返回值

(`T | undefined`): 返回数组中第 n 个元素。

## 示例

```typescript
nth([1, 2, 3], 1); // => 2
nth([1, 2, 3], -1); // => 3
```
2 changes: 1 addition & 1 deletion src/compat/_internal/stubA.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export function stubA() {
return 'A';
return 'a';
}
2 changes: 1 addition & 1 deletion src/compat/_internal/stubB.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export function stubB() {
return 'B';
return 'b';
}
62 changes: 62 additions & 0 deletions src/compat/array/nth.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { describe, expect, it } from 'vitest';
import { nth } from './nth';
import { noop } from '../../function';
import { range } from '../../math';
import { falsey } from '../_internal/falsey';
import { stubA } from '../_internal/stubA';
import { stubB } from '../_internal/stubB';

describe('nth', () => {
const array = ['a', 'b', 'c', 'd'];

it('should get the nth element of `array`', () => {
const actual = array.map((value, index) => nth(array, index));

expect(actual).toEqual(array);
});

it('should work with a negative `n`', () => {
const actual = range(1, array.length + 1).map(n => nth(array, -n));

expect(actual).toEqual(['d', 'c', 'b', 'a']);
});

it('should coerce `n` to an integer', () => {
let values = falsey;
let expected = values.map(stubA);

// @ts-expect-error
let actual = values.map(n => (n ? nth(array, n) : nth(array)));

expect(actual).toEqual(expected);

values = ['1', 1.6];
expected = values.map(stubB);

// @ts-expect-error
actual = values.map(n => nth(array, n));

expect(actual).toEqual(expected);
});

it('should return `undefined` for empty arrays', () => {
const values = [null, undefined, []];
const expected = values.map(noop);

const actual = values.map(array => nth(array, 1));

expect(actual).toEqual(expected);
});

it('should return `undefined` for non-indexes', () => {
const array = [1, 2];
const values = [Infinity, array.length];
const expected = values.map(noop);

array[-1] = 3;

const actual = values.map(n => nth(array, n));

expect(actual).toEqual(expected);
});
});
27 changes: 27 additions & 0 deletions src/compat/array/nth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { isArrayLikeObject } from '../predicate/isArrayLikeObject.ts';
import { toInteger } from '../util/toInteger.ts';

/**
* Gets the element at index `n` of `array`. If `n` is negative, the nth element from the end is returned.
*
* @param {ArrayLike<T> | null | undefined} array - The array to query.
* @param {number} [n=0] - The index of the element to return.
* @return {T | undefined} Returns the nth element of `array`.
*
* @example
* nth([1, 2, 3], 1); // => 2
* nth([1, 2, 3], -1); // => 3
*/
export function nth<T>(array: ArrayLike<T> | null | undefined, n: number = 0): T | undefined {
if (!isArrayLikeObject(array) || array.length === 0) {
return undefined;
}

n = toInteger(n);

if (n < 0) {
n += array.length;
}

return array[n];
}
1 change: 1 addition & 0 deletions src/compat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export { intersectionBy } from './array/intersectionBy.ts';
export { join } from './array/join.ts';
export { last } from './array/last.ts';
export { lastIndexOf } from './array/lastIndexOf.ts';
export { nth } from './array/nth.ts';
export { orderBy } from './array/orderBy.ts';
export { pull } from './array/pull.ts';
export { sample } from './array/sample.ts';
Expand Down

0 comments on commit f7abb57

Please sign in to comment.