feat(every): Add every function (#475)

* feat(every): Add every function

* feat(every): Add every function test code

* feat(every): Add every function docs

* feat(every): Add every function bench
This commit is contained in:
Gonhong Cheon 2024-09-28 22:23:30 +09:00 committed by GitHub
parent 819d64ecfa
commit b0daa7377d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 283 additions and 0 deletions

View File

@ -0,0 +1,42 @@
import { bench, describe } from 'vitest';
import { every as everyEsToolkit } from 'es-toolkit';
import { every as everyLodash } from 'lodash';
const generateArray = (length: number, max: number) => Array.from({ length }, () => Math.floor(Math.random() * max));
const array = generateArray(1_000_000, 1000);
describe('every, all true', () => {
const alwaysTruePredicate = () => true;
bench('es-toolkit/every, all true', () => {
everyEsToolkit(array, alwaysTruePredicate);
});
bench('lodash/every, all true', () => {
everyLodash(array, alwaysTruePredicate);
});
});
describe('every, all false', () => {
const alwaysFalsePredicate = () => false;
bench('es-toolkit/every, all false', () => {
everyEsToolkit(array, alwaysFalsePredicate);
});
bench('lodash/every, all false', () => {
everyLodash(array, alwaysFalsePredicate);
});
});
describe('every, fail in middle', () => {
const middleFailPredicate = (n: number, index: number) => index < array.length / 2;
bench('es-toolkit/every, fail in middle', () => {
everyEsToolkit(array, middleFailPredicate);
});
bench('lodash/every, fail in middle', () => {
everyLodash(array, middleFailPredicate);
});
});

View File

@ -0,0 +1,44 @@
# every
컬렉션의 모든 요소가 주어진 조건을 만족하는지 확인해요.
이 함수는 배열, 객체, 문자열을 처리할 수 있으며, 컬렉션의 모든 요소가 조건을 만족하면 `true`, 그렇지 않으면 `false`를 반환해요.
만약 컬렉션이 `null` 또는 `undefined`일 경우에는 `true`를 반환해요.
빈 배열 `[]`, 빈 문자열 `''`, 빈 객체 `{}`는 기본적으로 `true`를 반환해요.
## 인터페이스
```typescript
function every<T>(
collection: T[] | { [key: string]: T } | string | null | undefined,
predicate: (value: T, indexOrKey: number | string) => boolean
): boolean;
```
### 파라미터
- `collection` (`T[] | { [key: string]: T } | string | null | undefined`): 조건을 확인할 배열, 객체, 문자열 또는 `null`/`undefined`.
- `predicate` (`(value: T, indexOrKey: number | string) => boolean`): 각 요소를 테스트할 함수에요. 현재 요소의 값과 인덱스(또는 객체의 키)를 받아요.
### 반환 값
(`boolean`): 컬렉션의 모든 요소가 조건을 만족하거나 컬렉션이 비어있을 때는 `true`, 그렇지 않으면 `false` 를 반환해요.
## Examples
```typescript
import { every } from 'es-toolkit/collection';
const numbers = [1, 2, 3];
const allPositive = every(numbers, (value) => value > 0);
console.log(allPositive); // true
const str = 'abc';
const allLowerCase = every(str, (char) => /[a-z]/.test(char));
console.log(allLowerCase); // true
const obj = { a: 1, b: 2, c: 3 };
const allGreaterThanZero = every(obj, (value) => value > 0);
console.log(allGreaterThanZero); // true
```

View File

@ -0,0 +1,44 @@
# every
Checks if all elements in a collection pass the provided predicate.
This function can handle arrays, objects, and strings.
It returns true if all elements or characters in the collection satisfy the predicate function, or if the collection is null, undefined, empty, or has no elements.
Note: Empty arrays `[]`, empty strings `''`, and empty objects `{}` return `true` by default.
## Signature
```typescript
function every<T>(
collection: T[] | { [key: string]: T } | string | null | undefined,
predicate: (value: T, indexOrKey: number | string) => boolean
): boolean;
```
### Parameters
- `collection` (`T[] | { [key: string]: T } | string | null | undefined`): The collection to check, which can be an array, object, string, or `null`/`undefined`.
- `predicate` (`(value: T, indexOrKey: number | string) => boolean`): A function to test each element. It receives the current element's value and index (or key in the case of objects).
### Returns
(`boolean`): Returns `true` if all elements pass the predicate, or if the collection is empty, `null`, or `undefined`. Returns `false` if any element fails the predicate.
## Examples
```typescript
import { every } from 'es-toolkit/collection';
const numbers = [1, 2, 3];
const allPositive = every(numbers, (value) => value > 0);
console.log(allPositive); // true
const str = 'abc';
const allLowerCase = every(str, (char) => /[a-z]/.test(char));
console.log(allLowerCase); // true
const obj = { a: 1, b: 2, c: 3 };
const allGreaterThanZero = every(obj, (value) => value > 0);
console.log(allGreaterThanZero); // true
```

77
src/array/every.spec.ts Normal file
View File

@ -0,0 +1,77 @@
import { describe, expect, it } from 'vitest';
import { every } from './every';
describe('every', () => {
it('should return true for array with all elements passing predicate', () => {
const arr = [1, 2, 3, 4];
const result = every(arr, n => n > 0);
expect(result).toBe(true);
});
it('should return false for array when an element does not pass predicate', () => {
const arr = [1, 2, 3, -4];
const result = every(arr, n => n > 0);
expect(result).toBe(false);
});
it('should return true for empty array', () => {
const result = every([], () => false);
expect(result).toBe(true);
});
it('should return true for object with all values passing predicate', () => {
const obj = { a: 1, b: 2, c: 3 };
const result = every(obj, value => value > 0);
expect(result).toBe(true);
});
it('should return false for object when a value does not pass predicate', () => {
const obj = { a: 1, b: -2, c: 3 };
const result = every(obj, value => value > 0);
expect(result).toBe(false);
});
it('should return true for empty object', () => {
const result = every({}, () => false);
expect(result).toBe(true);
});
it('should return true for string where all characters pass predicate', () => {
const str = 'hello';
const result = every(str, char => char !== ' ');
expect(result).toBe(true);
});
it('should return false for string where a character does not pass predicate', () => {
const str = 'hello world';
const result = every(str, char => char !== ' ');
expect(result).toBe(false);
});
it('should return true for empty string', () => {
const result = every('', () => false);
expect(result).toBe(true);
});
it('should return true for null', () => {
const result = every(null, () => false);
expect(result).toBe(true);
});
it('should return true for undefined', () => {
const result = every(undefined, () => false);
expect(result).toBe(true);
});
it('should correctly handle indices for arrays', () => {
const arr = [1, 2, 3];
const result = every(arr, (n, index) => index < 3);
expect(result).toBe(true);
});
it('should correctly handle keys for objects', () => {
const obj = { a: 1, b: 2, c: 3 };
const result = every(obj, (value, key) => ['a', 'b', 'c'].includes(key));
expect(result).toBe(true);
});
});

75
src/array/every.ts Normal file
View File

@ -0,0 +1,75 @@
/**
* Checks if all elements in a collection pass the predicate.
*
* Returns `true` if all elements in an array, object, or string satisfy the predicate,
* or if the collection is `null` or `undefined`.
*
* Note: Empty arrays `[]`, empty strings `''`, and empty objects `{}` return `true` by default.
*
* @template T The type of elements in the collection.
* @param {T[] | { [key: string]: T } | string | null | undefined} collection - The collection to check.
* @param {(value: T, indexOrKey: number | string) => boolean} predicate - The function to test each element.
* @returns {boolean} `true` if all elements pass the predicate, `false` otherwise.
*
* @example
* every([1, 2, 3], (value) => value > 0); // true
* @example
* every('abc', (char) => /[a-z]/.test(char)); // true
* @example
* every({ a: 1, b: 2 }, (value) => value > 0); // true
*/
export function every<T>(collection: T[] | null | undefined, predicate: (value: T, index: number) => boolean): boolean;
export function every<T>(
collection: { [key: string]: T } | null | undefined,
predicate: (value: T, key: string) => boolean
): boolean;
export function every(
collection: string | null | undefined,
predicate: (value: string, index: number) => boolean
): boolean;
export function every<T>(
collection: T[] | { [key: string]: T } | string | null | undefined,
predicate: (value: any, index: any) => boolean
): boolean {
if (collection == null) {
return true;
}
if (Array.isArray(collection)) {
if (collection.length === 0) {
return true;
}
for (let i = 0; i < collection.length; i++) {
if (!predicate(collection[i], i)) {
return false;
}
}
return true;
}
if (typeof collection === 'string') {
if (collection.length === 0) {
return true;
}
for (let i = 0; i < collection.length; i++) {
if (!predicate(collection[i], i)) {
return false;
}
}
return true;
}
const keys = Object.keys(collection);
if (keys.length === 0) {
return true;
}
for (const key of keys) {
if (!predicate(collection[key], key)) {
return false;
}
}
return true;
}

View File

@ -9,6 +9,7 @@ export { drop } from './drop.ts';
export { dropRight } from './dropRight.ts';
export { dropRightWhile } from './dropRightWhile.ts';
export { dropWhile } from './dropWhile.ts';
export { every } from './every.ts';
export { fill } from './fill.ts';
export { flatMap } from './flatMap.ts';
export { flatMapDeep } from './flatMapDeep.ts';