Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add chunk to fx #291

Merged
merged 2 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
@ppeeou @shine1594 @hg-pyun

# source
/src/ @ppeeou @shine1594
/src/ @ppeeou
21 changes: 21 additions & 0 deletions src/Lazy/fx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { DeepFlat } from "../types/DeepFlat";
import type IterableInfer from "../types/IterableInfer";
import type Key from "../types/Key";
import type { SyncReducer } from "../types/Reducer";
import chunk from "./chunk";
import concurrent from "./concurrent";
import drop from "./drop";
import filter from "./filter";
Expand Down Expand Up @@ -189,6 +190,16 @@ class FxAsyncIterable<A> {
return new FxAsyncIterable(f(this.asyncIterable));
}

/**
* Returns AsyncIterable of elements split into groups the length of size.
* If AsyncIterableIterator can't be split evenly, the final chunk will be the remaining elements.
*
* see {@link https://fxts.dev/docs/chunk | chunk}
*/
chunk(size: number) {
return new FxAsyncIterable(chunk(size, this.asyncIterable));
}

/**
* Concurrent is used to balance the load of multiple asynchronous requests.
* The first argument receives a number that controls the number of loads, and the second argument is an AsyncIterable.
Expand Down Expand Up @@ -473,6 +484,16 @@ export class FxIterable<A> {
return new FxIterable(f(this.iterable));
}

/**
* Returns Iterable of elements split into groups the length of size.
* If iterableIterator can't be split evenly, the final chunk will be the remaining elements.
*
* see {@link https://fxts.dev/docs/chunk | chunk}
*/
chunk(size: number) {
return new FxIterable(chunk(size, this.iterable));
}

/**
* Returns AsyncIterable, `toAsync` used when you want to handle Promise values inside Iterable.
*
Expand Down
39 changes: 39 additions & 0 deletions test/Lazy/chunk.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
concurrent,
delay,
filter,
fx,
map,
pipe,
range,
Expand Down Expand Up @@ -46,6 +47,25 @@ describe("chunk", function () {
const res = pipe(range(1, 12), chunk(3), toArray);
expect(res).toEqual(expected);
});

it.each([
[
[1, 2, 3, 4],
[
[1, 2],
[3, 4],
],
],
[
[1, 2, 3, 4, 5],
[[1, 2], [3, 4], [5]],
],
])(
"should be able to be used as a chaining method in the `fx`",
function (data: number[], result: number[][]) {
expect(fx(data).chunk(2).toArray()).toEqual(result);
},
);
});

describe("async", function () {
Expand Down Expand Up @@ -132,6 +152,25 @@ describe("chunk", function () {
expect(res).toEqual(expected);
});

it.each([
[
[1, 2, 3, 4],
[
[1, 2],
[3, 4],
],
],
[
[1, 2, 3, 4, 5],
[[1, 2], [3, 4], [5]],
],
])(
"should be able to be used as a chaining method in the `fx`",
async function (data: number[], result: number[][]) {
expect(await fx(data).toAsync().chunk(2).toArray()).toEqual(result);
},
);

it("should be passed concurrent object when job works concurrently", async function () {
const mock = generatorMock();
const iter = chunk(3, mock);
Expand Down
18 changes: 14 additions & 4 deletions type-check/Lazy/chunk.test.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
import { chunk, pipe, toAsync } from "../../src";
import { chunk, fx, pipe, toAsync } from "../../src";
import type Cast from "../../src/types/Cast";
import * as Test from "../../src/types/Test";

const { checks, check } = Test;

const res1 = chunk(1, []);
const res2 = chunk(1, [1, 2, 3]);
const res3 = chunk(1, toAsync([1, 2, 3]));

const res4 = pipe([1, 2, 3, 4], chunk(1));
const res5 = pipe(Promise.resolve([1, 2, 3, 4]), chunk(1));
const res6 = pipe(toAsync([1, 2, 3, 4]), chunk(1));
const res7 = fx([1, 2, 3, 4]).chunk(2);
const res8 = fx([1, 2, 3, 4]).toAsync().chunk(2);

checks([
check<typeof res1, IterableIterator<never[]>, Test.Pass>(),

check<typeof res2, IterableIterator<number[]>, Test.Pass>(),
check<typeof res3, AsyncIterableIterator<number[]>, Test.Pass>(),

check<typeof res4, IterableIterator<number[]>, Test.Pass>(),
check<typeof res5, Promise<IterableIterator<number[]>>, Test.Pass>(),
check<typeof res6, AsyncIterableIterator<number[]>, Test.Pass>(),
check<
typeof res7,
Cast<IterableIterator<number[]>, typeof res7>,
Test.Pass
>(),
check<
typeof res8,
Cast<AsyncIterableIterator<number[]>, typeof res8>,
Test.Pass
>(),
]);
Loading