Skip to content

Commit

Permalink
Add join/asyncJoin functions
Browse files Browse the repository at this point in the history
  • Loading branch information
jdesrosiers committed Jun 22, 2023
1 parent a9f6fb6 commit 0ca3c02
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 7 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ console.log(result);
* **asyncCollectObject**: (iterator: AsyncIterable) => Promise<Object>;

Same as `collectObject`, but works with promises.
* **join**: (separator: string, iterator: Iterable) => string;

Collect all the items in the iterator into a string separated by the
separator token.
* **asyncJoin**: (separator: string, iterator: AsyncIterable) => Promise<string>;

Same as `join`, but works with promises.
* **pipe**: (iterator: Iterable | AsyncIterable, ...fns: Function) => any;

Starting with an iterator, apply any number of functions to transform the
Expand Down
1 change: 1 addition & 0 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export {
asyncCollectSet as collectSet,
asyncCollectMap as collectMap,
asyncCollectObject as collectObject,
asyncJoin as join,
pipe
} from "./index.js";
58 changes: 57 additions & 1 deletion lib/collectors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import {
collectArray, asyncCollectArray,
collectSet, asyncCollectSet,
collectMap, asyncCollectMap,
collectObject, asyncCollectObject
collectObject, asyncCollectObject,
join, asyncJoin,
empty
} from "./index.js";


Expand Down Expand Up @@ -142,3 +144,57 @@ describe("asyncCollectObject", () => {
expect(result).to.eql({ "foo": 1, "bar": 2, "baz": 3 });
});
});

describe("join", () => {
it("empty", () => {
const result = join(",", empty());
expect(result).to.equal("");
});

it("one item", () => {
const subject = (function* () {
yield "foo";
}());

const result = join(",", subject);
expect(result).to.equal("foo");
});

it("multiple items", () => {
const subject = (function* () {
yield "foo";
yield "bar";
yield "baz";
}());

const result = join(",", subject);
expect(result).to.equal("foo,bar,baz");
});
});

describe("asyncJoin", () => {
it("empty", async () => {
const result = await asyncJoin(",", empty());
expect(result).to.equal("");
});

it("one item", async () => {
const subject = (async function* () {
yield "foo";
}());

const result = await asyncJoin(",", subject);
expect(result).to.equal("foo");
});

it("multiple items", async () => {
const subject = (async function* () {
yield "foo";
yield "bar";
yield "baz";
}());

const result = await asyncJoin(",", subject);
expect(result).to.equal("foo,bar,baz");
});
});
6 changes: 0 additions & 6 deletions lib/generators.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -531,12 +531,6 @@ describe("empty", () => {
});
});

describe("empty", () => {
it("should be empty", () => {
expect([...empty()]).to.equal([]);
});
});

describe("zip", () => {
it("same number of items", () => {
const iter1 = (function* () {
Expand Down
12 changes: 12 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,5 +148,17 @@ export const asyncCollectMap: <A, B>(iterator: AsyncIterable<[A, B]>) => Promise
export const collectObject: <A>(iterator: Iterable<[string, A]>) => Record<string, A>;
export const asyncCollectObject: <A>(iterator: AsyncIterable<[string, A]>) => Promise<Record<string, A>>;

export const join: (
(separator: string, iterator: Iterable<string>) => string
) & (
(separator: string) => (iterator: Iterable<string>) => string
);

export const asyncJoin: (
(separator: string, iterator: Iterable<string> | AsyncIterable<string>) => Promise<string>
) & (
(separator: string) => (iterator: Iterable<string> | AsyncIterable<string>) => Promise<string>
);

// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any
export const pipe: <A>(iterator: Iterable<any> | AsyncIterable<any>, ...fns: Function[]) => A;
20 changes: 20 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,26 @@ export const asyncCollectObject = async (iter) => {
return result;
};

export const join = curry((separator, iter) => {
let result = head(iter) || "";

for (const n of iter) {
result += separator + n;
}

return result;
});

export const asyncJoin = curry(async (separator, iter) => {
let result = await asyncHead(iter) || "";

for await (const n of iter) {
result += separator + n;
}

return result;
});

const getIterator = (iter) => {
if (typeof iter?.[Symbol.iterator] === "function") {
return iter[Symbol.iterator]();
Expand Down

0 comments on commit 0ca3c02

Please sign in to comment.