Skip to content

Commit

Permalink
feat: Add asyncSome to Array (#10)
Browse files Browse the repository at this point in the history
Adding a custom version of `some` that supports async predicates.
  • Loading branch information
arvinsiva authored Jan 30, 2024
1 parent a39f418 commit cbcf7a1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,33 @@ describe("array", () => {
).toThrow();
});
});

describe("asyncSome", () => {
it("returns true if any element matches predicate (even number)", async () => {
// given an array of even and odd numbers
const a = [1, 2, 3, 4, 5];
// when we call asyncSome with a predicate that checks for even numbers
const result = await a.asyncSome((el) => Promise.resolve(el % 2 === 0));
// then expect asyncSome to return true
expect(result).toBe(true);
});

it("returns false if no elements match predicate (even number)", async () => {
// given an array of odd numbers
const a = [1, 3, 5];
// when we call asyncSome with a predicate that checks for even numbers
const result = await a.asyncSome((el) => Promise.resolve(el % 2 === 0));
// then expect asyncSome to return false
expect(result).toBe(false);
});

it("returns false if the array is empty", async () => {
// given an empty array
const a: number[] = [];
// when we call asyncSome with a predicate that checks for even numbers
const result = await a.asyncSome((el) => Promise.resolve(el % 2 === 0));
// then expect asyncSome to return false
expect(result).toBe(false);
});
});
});
10 changes: 10 additions & 0 deletions src/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ declare global {
each(f: (el: T, index: number, array: T[]) => any): T[];
/** Helper for filtering arrays on async predicates. */
asyncFilter(predicate: (v: T) => Promise<boolean>): Promise<Array<T>>;
asyncSome(predicate: (v: T) => boolean | Promise<boolean>): Promise<boolean>;
asyncMap<V>(f: (el: T, index: number, array: T[]) => Promise<V>): Promise<V[]>;
asyncForEach(f: (el: T, index: number, array: T[]) => Promise<any>): Promise<void>;
sum(this: Array<number | undefined>): number;
Expand Down Expand Up @@ -97,6 +98,7 @@ declare global {
each(f: (el: T, index: number, array: T[]) => any): T[];
/** Helper for filtering arrays on async predicates. */
asyncFilter(predicate: (v: T) => Promise<boolean>): Promise<Array<T>>;
asyncSome(predicate: (v: T) => boolean | Promise<boolean>): Promise<boolean>;
asyncMap<V>(f: (el: T, index: number, array: T[]) => Promise<V>): Promise<V[]>;
asyncForEach(f: (el: T, index: number, array: T[]) => Promise<any>): Promise<void>;
sum(this: ReadonlyArray<number | undefined>): number;
Expand Down Expand Up @@ -219,6 +221,14 @@ Array.prototype.asyncFilter = async function <T>(
return this.filter((_v, index) => results[index]);
};

Array.prototype.asyncSome = async function <T>(
this: Array<T>,
predicate: (v: T) => Promise<boolean>,
): Promise<boolean> {
const asyncResults = this.map((el) => predicate(el).then((result) => result || Promise.reject()));
return await Promise.any(asyncResults).catch(() => false);
};

Array.prototype.asyncMap = async function <T, V>(
this: Array<T>,
f: (el: T, index: number, array: T[]) => Promise<V>,
Expand Down

0 comments on commit cbcf7a1

Please sign in to comment.