Skip to content

Commit

Permalink
feat: add asyncSome to array
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinsiva committed Jan 30, 2024
1 parent a39f418 commit 47342c0
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,34 @@ describe("array", () => {
).toThrow();
});
});

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

it("returns true if any element matches sync/async predicate (1 or even number)", async () => {
// given an array of even and odd numbers which includes 1
const a = [1, 2, 3, 4, 5];
// then expect asyncSome to return true
expect(await a.asyncSome((el) => el === 1 || Promise.resolve(el % 2 === 0))).toBe(true);
});

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

it("returns false if the array is empty", async () => {
// given an empty array
const a: number[] = [];
// then expect asyncSome to return false
expect(await a.asyncSome((el) => Promise.resolve(el % 2 === 0))).toBe(false);
});
});
});
25 changes: 25 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,29 @@ 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) => boolean | Promise<boolean>,
): Promise<boolean> {
const asyncResults: Promise<boolean>[] = [];
for (const el of this) {
const result = predicate(el);
if (typeof result === "boolean") {
if (result) {
return true;
}
} else {
asyncResults.push(result);
}
}
for (const result of asyncResults) {
if (await result) {
return true;
}
}
return 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 47342c0

Please sign in to comment.