Skip to content

Commit

Permalink
feat: 🎸 chunk(), shuffle()
Browse files Browse the repository at this point in the history
  • Loading branch information
jamashita committed Apr 23, 2024
1 parent 7c56b5b commit 84c7bf5
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 8 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
"update:upgrade": "ncu --packageManager yarn --deep --upgrade"
},
"dependencies": {
"@jamashita/anden": "2.7.0"
"@jamashita/anden": "2.7.0",
"@jamashita/steckdose": "1.32.0"
},
"devDependencies": {
"@biomejs/biome": "1.6.4",
Expand Down
45 changes: 44 additions & 1 deletion src/sequence/ASequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type Nullable,
type Undefinable
} from '@jamashita/anden/type';
import { Random } from '@jamashita/steckdose/random';
import { type NarrowingBinaryPredicate, Quantity } from '../collection/index.js';
import type { Sequence } from './Sequence.js';

Expand All @@ -22,19 +23,49 @@ export abstract class ASequence<out V> extends Quantity<number, V> implements Se

public abstract add(value: V): ASequence<V>;

public abstract chunk(size: number): ASequence<ASequence<V>>;

public abstract duplicate(): ASequence<V>;

public abstract override filter<W extends V>(predicate: NarrowingBinaryPredicate<V, W, number>): ASequence<W>;
public abstract override filter(predicate: BinaryPredicate<V, number>): ASequence<V>;

public abstract override filter<W extends V>(predicate: NarrowingBinaryPredicate<V, W, number>): ASequence<W>;

public abstract override map<W>(mapping: Mapping<V, W>): ASequence<W>;

public abstract remove(key: number): ASequence<V>;

public abstract set(key: number, value: V): ASequence<V>;

public abstract shuffle(): ASequence<V>;

public abstract sort(comparator: BinaryFunction<V, V, number>): ASequence<V>;

protected chunkInternal(size: number): Array<Array<V>> {
if (size <= 0) {
return [];
}
if (!Kind.isInteger(size)) {
return [];
}

const arr: Array<Array<V>> = [];
let chunk: Array<V> = [];

this.sequence.forEach((v: V, i: number) => {
if (i % size === 0 && i !== 0) {
arr.push(chunk);
chunk = [];
}

chunk.push(v);
});

arr.push(chunk);

return arr;
}

public contains(value: V): boolean {
const found: Undefinable<V> = this.sequence.find((v: V) => {
if (v === value) {
Expand Down Expand Up @@ -163,6 +194,18 @@ export abstract class ASequence<out V> extends Quantity<number, V> implements Se
return [...this.sequence.slice(0, key), value, ...this.sequence.slice(key + 1)];
}

protected shuffleInternal(): Array<V> {
const arr: Array<V> = [...this.sequence];

for (let i: number = arr.length - 1; i >= 0; i--) {
const j: number = Random.integer(0, i);
// biome-ignore lint/style/noNonNullAssertion: <explanation>
[arr[i], arr[j]] = [arr[j]!, arr[i]!];
}

return arr;
}

public size(): number {
return this.sequence.length;
}
Expand Down
14 changes: 14 additions & 0 deletions src/sequence/ImmutableSequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ export class ImmutableSequence<out V> extends ASequence<V> {
return ImmutableSequence.ofArray([...this.sequence, value]);
}

public chunk(size: number): ImmutableSequence<ImmutableSequence<V>> {
const sequences: Array<ImmutableSequence<V>> = this.chunkInternal(size).map((arr: Array<V>) => {
return ImmutableSequence.ofArray(arr);
});

return ImmutableSequence.ofArray(sequences);
}

public duplicate(): ImmutableSequence<V> {
if (this.isEmpty()) {
return ImmutableSequence.empty();
Expand All @@ -50,7 +58,9 @@ export class ImmutableSequence<out V> extends ASequence<V> {
}

public filter<W extends V>(predicate: NarrowingBinaryPredicate<V, W, number>): ImmutableSequence<W>;

public filter(predicate: BinaryPredicate<V, number>): ImmutableSequence<V>;

public filter<W extends V = V>(predicate: NarrowingBinaryPredicate<V, W, number>): ImmutableSequence<W> {
return ImmutableSequence.ofArray(this.filterInternal(predicate));
}
Expand Down Expand Up @@ -87,6 +97,10 @@ export class ImmutableSequence<out V> extends ASequence<V> {
return ImmutableSequence.ofArray(sequence);
}

public shuffle(): ImmutableSequence<V> {
return ImmutableSequence.ofArray(this.shuffleInternal());
}

public sort(comparator: BinaryFunction<V, V, number>): ImmutableSequence<V> {
const arr: Array<V> = this.toArray();

Expand Down
14 changes: 14 additions & 0 deletions src/sequence/MutableSequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,22 @@ export class MutableSequence<out V> extends ASequence<V> {
return this;
}

public chunk(size: number): ASequence<ASequence<V>> {
const sequences: Array<MutableSequence<V>> = this.chunkInternal(size).map((arr: Array<V>) => {
return MutableSequence.ofArray(arr);
});

return MutableSequence.ofArray(sequences);
}

public duplicate(): MutableSequence<V> {
return MutableSequence.ofArray([...this.sequence]);
}

public filter<W extends V>(predicate: NarrowingBinaryPredicate<V, W, number>): MutableSequence<W>;

public filter(predicate: BinaryPredicate<V, number>): MutableSequence<V>;

public filter<W extends V = V>(predicate: NarrowingBinaryPredicate<V, W, number>): MutableSequence<W> {
return MutableSequence.ofArray(this.filterInternal(predicate));
}
Expand All @@ -63,6 +73,10 @@ export class MutableSequence<out V> extends ASequence<V> {
return this;
}

public shuffle(): ASequence<V> {
return MutableSequence.ofArray(this.shuffleInternal());
}

public sort(comparator: BinaryFunction<V, V, number>): MutableSequence<V> {
const arr: Array<V> = [...this.sequence];

Expand Down
6 changes: 5 additions & 1 deletion src/sequence/ReadonlySequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ import type { BinaryFunction, BinaryPredicate, Cloneable, Mapping } from '@jamas
import type { Collection, NarrowingBinaryPredicate } from '../collection/index.js';

export interface ReadonlySequence<out V> extends Collection<number, V>, Cloneable<ReadonlySequence<V>> {
filter<W extends V>(predicate: NarrowingBinaryPredicate<V, W, number>): ReadonlySequence<W>;
chunk(size: number): ReadonlySequence<ReadonlySequence<V>>;

filter(predicate: BinaryPredicate<V, number>): ReadonlySequence<V>;

filter<W extends V>(predicate: NarrowingBinaryPredicate<V, W, number>): ReadonlySequence<W>;

map<W>(mapping: Mapping<V, W>): ReadonlySequence<W>;

reduce(reducer: BinaryFunction<V, V, V>, initialValue?: V): V;

shuffle(): ReadonlySequence<V>;

sort(comparator: BinaryFunction<V, V, number>): ReadonlySequence<V>;

toArray(): Array<V>;
Expand Down
8 changes: 8 additions & 0 deletions src/sequence/mock/MockSequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export class MockSequence<out V> extends ASequence<V> {
throw new UnimplementedError();
}

public chunk(): MockSequence<MockSequence<V>> {
throw new UnimplementedError();
}

public duplicate(): MockSequence<V> {
throw new UnimplementedError();
}
Expand All @@ -30,6 +34,10 @@ export class MockSequence<out V> extends ASequence<V> {
throw new UnimplementedError();
}

public shuffle(): MockSequence<V> {
throw new UnimplementedError();
}

public sort(): MockSequence<V> {
throw new UnimplementedError();
}
Expand Down
Loading

0 comments on commit 84c7bf5

Please sign in to comment.