Skip to content

Commit

Permalink
Merge pull request #276 from jamashita/develop
Browse files Browse the repository at this point in the history
chore(deps): bump ip from 2.0.0 to 2.0.1
  • Loading branch information
jamashita authored Apr 23, 2024
2 parents 4208c71 + cc5bb67 commit 3c9fdfe
Show file tree
Hide file tree
Showing 18 changed files with 575 additions and 302 deletions.
13 changes: 13 additions & 0 deletions .idea/material_theme_project_new.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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
5 changes: 5 additions & 0 deletions src/address/AddressError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { CollectionError } from '../collection/index.js';

export class AddressError extends CollectionError {
// NOOP
}
1 change: 1 addition & 0 deletions src/address/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './mock/index.js';
export * from './Address.js';
export * from './AddressError.js';
export * from './ImmutableAddress.js';
export * from './MutableAddress.js';
export * from './ReadonlyAddress.js';
5 changes: 5 additions & 0 deletions src/collection/CollectionError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { RuntimeError } from '@jamashita/anden/error';

export class CollectionError extends RuntimeError {
// NOOP
}
1 change: 1 addition & 0 deletions src/collection/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './Collection.js';
export * from './CollectionError.js';
export * from './Quantity.js';
5 changes: 5 additions & 0 deletions src/dictionary/DictionaryError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { CollectionError } from '../collection/index.js';

export class DictionaryError extends CollectionError {
// NOOP
}
3 changes: 2 additions & 1 deletion src/dictionary/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './mock/index.js';
export * from './Dictionary.js';
export * from './DictionaryError.js';
export * from './ImmutableDictionary.js';
export * from './MutableDictionary.js';
export * from './Dictionary.js';
export * from './ReadonlyDictionary.js';
54 changes: 49 additions & 5 deletions src/sequence/ASequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ 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';
import { SequenceError } from './SequenceError.js';

export abstract class ASequence<out V> extends Quantity<number, V> implements Sequence<V> {
protected sequence: Array<V>;
Expand All @@ -22,19 +24,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) {
throw new SequenceError(`CHUNK SIZE MUST BE GREATER THAN 0. GIVEN: ${size}`);
}
if (!Kind.isInteger(size)) {
throw new SequenceError(`CHUNK SIZE MUST BE INTEGER. GIVEN: ${size}`);
}

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 @@ -135,10 +167,10 @@ export abstract class ASequence<out V> extends Quantity<number, V> implements Se

protected removeInternal(key: number): Array<V> {
if (!Kind.isInteger(key)) {
return this.sequence;
throw new SequenceError(`REMOVE KEY MUST BE INTEGER. GIVEN: ${key}`);
}
if (key < 0 || this.sequence.length <= key) {
return this.sequence;
throw new SequenceError(`REMOVE KEY IS OUT OF BOUND. GIVEN: ${key}`);
}

return [...this.sequence.slice(0, key), ...this.sequence.slice(key + 1)];
Expand All @@ -154,15 +186,27 @@ export abstract class ASequence<out V> extends Quantity<number, V> implements Se

protected setInternal(key: number, value: V): Array<V> {
if (!Kind.isInteger(key)) {
return this.sequence;
throw new SequenceError(`SET KEY MUST BE INTEGER. GIVEN: ${key}`);
}
if (key < 0 || this.sequence.length <= key) {
return this.sequence;
throw new SequenceError(`SET KEY IS OUT OF BOUND. GIVEN: ${key}`);
}

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
5 changes: 5 additions & 0 deletions src/sequence/SequenceError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { CollectionError } from '../collection/CollectionError.js';

export class SequenceError extends CollectionError {
// NOOP
}
45 changes: 25 additions & 20 deletions src/sequence/__tests__/ImmutableSequence.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { MockValueObject } from '@jamashita/anden/object';
import type { Nullable } from '@jamashita/anden/type';
import { ImmutableSequence } from '../ImmutableSequence.js';
import { SequenceError } from '../SequenceError.js';

describe('ImmutableSequence', () => {
describe('await', () => {
Expand Down Expand Up @@ -250,37 +251,40 @@ describe('ImmutableSequence', () => {
expect(sequence2.get(1)).toBe(value2);
});

it('returns itself when given key is greater than sequence length', () => {
it('throws SequenceError when given key is greater than sequence length', () => {
const value1: MockValueObject<number> = new MockValueObject(1);
const value2: MockValueObject<number> = new MockValueObject(2);
const value3: MockValueObject<number> = new MockValueObject(3);

const sequence1: ImmutableSequence<MockValueObject<number>> = ImmutableSequence.ofArray([value1, value2, value3]);
const sequence2: ImmutableSequence<MockValueObject<number>> = sequence1.remove(3);

expect(sequence1).toBe(sequence2);
expect(() => {
sequence1.remove(3);
}).toThrow(SequenceError);
});

it('returns itself when given key is less than 0', () => {
it('throws SequenceError when given key is less than 0', () => {
const value1: MockValueObject<number> = new MockValueObject(1);
const value2: MockValueObject<number> = new MockValueObject(2);
const value3: MockValueObject<number> = new MockValueObject(3);

const sequence1: ImmutableSequence<MockValueObject<number>> = ImmutableSequence.ofArray([value1, value2, value3]);
const sequence2: ImmutableSequence<MockValueObject<number>> = sequence1.remove(-1);

expect(sequence1).toBe(sequence2);
expect(() => {
sequence1.remove(-1);
}).toThrow(SequenceError);
});

it('returns itself when given key is not integer', () => {
it('throws SequenceError when given key is not integer', () => {
const value1: MockValueObject<number> = new MockValueObject(1);
const value2: MockValueObject<number> = new MockValueObject(2);
const value3: MockValueObject<number> = new MockValueObject(3);

const sequence1: ImmutableSequence<MockValueObject<number>> = ImmutableSequence.ofArray([value1, value2, value3]);
const sequence2: ImmutableSequence<MockValueObject<number>> = sequence1.remove(0.8);

expect(sequence1).toBe(sequence2);
expect(() => {
sequence1.remove(0.8);
}).toThrow(SequenceError);
});
});

Expand Down Expand Up @@ -336,42 +340,43 @@ describe('ImmutableSequence', () => {
expect(sequence2.get(2)).toBe(value4);
});

it('returns itself when given key is less than 0', () => {
it('throws SequenceError when given key is less than 0', () => {
const value1: MockValueObject<number> = new MockValueObject(1);
const value2: MockValueObject<number> = new MockValueObject(2);
const value3: MockValueObject<number> = new MockValueObject(3);
const value4: MockValueObject<number> = new MockValueObject(4);

const sequence1: ImmutableSequence<MockValueObject<number>> = ImmutableSequence.ofArray([value1, value2, value3]);
const sequence2: ImmutableSequence<MockValueObject<number>> = sequence1.set(-1, value4);

expect(sequence1).toBe(sequence2);
expect(() => {
sequence1.set(-1, value4);
}).toThrow(SequenceError);
});

it('returns itself when given key is greater than sequence length', () => {
it('throws SequenceError when given key is greater than sequence length', () => {
const value1: MockValueObject<number> = new MockValueObject(1);
const value2: MockValueObject<number> = new MockValueObject(2);
const value3: MockValueObject<number> = new MockValueObject(3);
const value4: MockValueObject<number> = new MockValueObject(4);

const sequence1: ImmutableSequence<MockValueObject<number>> = ImmutableSequence.ofArray([value1, value2, value3]);

const sequence2: ImmutableSequence<MockValueObject<number>> = sequence1.set(sequence1.size(), value4);

expect(sequence1).toBe(sequence2);
expect(() => {
sequence1.set(sequence1.size(), value4);
}).toThrow(SequenceError);
});

it('returns itself when given key is not integer', () => {
it('throws SequenceError when given key is not integer', () => {
const value1: MockValueObject<number> = new MockValueObject(1);
const value2: MockValueObject<number> = new MockValueObject(2);
const value3: MockValueObject<number> = new MockValueObject(3);
const value4: MockValueObject<number> = new MockValueObject(4);

const sequence1: ImmutableSequence<MockValueObject<number>> = ImmutableSequence.ofArray([value1, value2, value3]);

const sequence2: ImmutableSequence<MockValueObject<number>> = sequence1.set(2.2, value4);

expect(sequence1).toBe(sequence2);
expect(() => {
sequence1.set(2.2, value4);
}).toThrow(SequenceError);
});
});

Expand Down
Loading

0 comments on commit 3c9fdfe

Please sign in to comment.