mirror of
https://github.com/toss/es-toolkit.git
synced 2024-11-23 19:24:52 +03:00
feat(times): Add times (#656)
This commit is contained in:
parent
42a4b9424b
commit
9edacf776f
16
benchmarks/performance/times.bench.ts
Normal file
16
benchmarks/performance/times.bench.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { bench, describe } from 'vitest';
|
||||||
|
import { times as timesCompatToolkit_ } from 'es-toolkit/compat';
|
||||||
|
import { times as timesLodash_ } from 'lodash';
|
||||||
|
|
||||||
|
const timesCompatToolkit = timesCompatToolkit_;
|
||||||
|
const timesLodash = timesLodash_;
|
||||||
|
|
||||||
|
describe('times', () => {
|
||||||
|
bench('es-toolkit/compat/times', () => {
|
||||||
|
timesCompatToolkit(1000, i => i * 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
bench('lodash/times', () => {
|
||||||
|
timesLodash(1000, i => i * 2);
|
||||||
|
});
|
||||||
|
});
|
3
src/compat/_internal/doubled.ts
Normal file
3
src/compat/_internal/doubled.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function doubled(n: number) {
|
||||||
|
return n * 2;
|
||||||
|
}
|
3
src/compat/_internal/stubArray.ts
Normal file
3
src/compat/_internal/stubArray.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function stubArray() {
|
||||||
|
return [];
|
||||||
|
}
|
@ -149,3 +149,4 @@ export { toNumber } from './util/toNumber.ts';
|
|||||||
export { toInteger } from './util/toInteger.ts';
|
export { toInteger } from './util/toInteger.ts';
|
||||||
export { toFinite } from './util/toFinite.ts';
|
export { toFinite } from './util/toFinite.ts';
|
||||||
export { eq } from './util/eq.ts';
|
export { eq } from './util/eq.ts';
|
||||||
|
export { times } from './util/times.ts';
|
||||||
|
58
src/compat/util/times.spec.ts
Normal file
58
src/compat/util/times.spec.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { times } from './times';
|
||||||
|
import { doubled } from '../_internal/doubled';
|
||||||
|
import { falsey } from '../_internal/falsey';
|
||||||
|
import { slice } from '../_internal/slice';
|
||||||
|
import { stubArray } from '../_internal/stubArray';
|
||||||
|
|
||||||
|
describe('times', () => {
|
||||||
|
it('should coerce non-finite `n` values to `0`', () => {
|
||||||
|
[-Infinity, NaN, Infinity].forEach(n => {
|
||||||
|
expect(times(n)).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should coerce `n` to an integer', () => {
|
||||||
|
const actual = times(2.6, n => n);
|
||||||
|
expect(actual).toEqual([0, 1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should provide correct `iteratee` arguments', () => {
|
||||||
|
let args: any;
|
||||||
|
|
||||||
|
times(1, function () {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions, prefer-rest-params
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(args).toEqual([0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use `_.identity` when `iteratee` is nullish', () => {
|
||||||
|
// eslint-disable-next-line no-sparse-arrays
|
||||||
|
const values = [, null, undefined];
|
||||||
|
const expected = values.map(() => [0, 1, 2]);
|
||||||
|
|
||||||
|
const actual = values.map((value, index) => (index ? times(3, value as any) : times(3)));
|
||||||
|
|
||||||
|
expect(actual).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an array of the results of each `iteratee` execution', () => {
|
||||||
|
expect(times(3, doubled)).toEqual([0, 2, 4]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty array for falsey and negative `n` values', () => {
|
||||||
|
const values = falsey.concat(-1, -Infinity);
|
||||||
|
const expected = values.map(stubArray);
|
||||||
|
|
||||||
|
const actual = values.map((value, index) => (index ? times(value as any) : times()));
|
||||||
|
|
||||||
|
expect(actual).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty array when `n > Number.MAX_SAFE_INTEGER`', () => {
|
||||||
|
expect(times(Number.MAX_SAFE_INTEGER + 1)).toEqual([]);
|
||||||
|
expect(times(Number.MAX_VALUE, doubled)).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
32
src/compat/util/times.ts
Normal file
32
src/compat/util/times.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { toInteger } from './toInteger';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes the iteratee n times, returning an array of the results of each invocation.
|
||||||
|
*
|
||||||
|
* The iteratee is invoked with one argument; (index).
|
||||||
|
*
|
||||||
|
* @template F The type of the iteratee function.
|
||||||
|
* @param {number} n - The number of times to invoke iteratee.
|
||||||
|
* @param {F extends (n: number) => any} [iteratee] - The function invoked per iteration. Default is identity.
|
||||||
|
* @returns {Array<ReturnType<F>>} - Returns the array of results.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* times(3, doubled); // => [0, 2, 4]
|
||||||
|
* times(4); // => [0, 1, 2, 3]
|
||||||
|
* times(2, () => 'es-toolkit') // => ['es-toolkit', 'es-toolkit']
|
||||||
|
*/
|
||||||
|
export function times<F extends (n: number) => any>(n?: number, iteratee?: F): Array<ReturnType<F>> {
|
||||||
|
n = toInteger(n);
|
||||||
|
|
||||||
|
if (n < 1 || !Number.isSafeInteger(n)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = new Array(n);
|
||||||
|
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
result[i] = typeof iteratee === 'function' ? iteratee(i) : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user