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

Refactor, type fixes. #27

Merged
merged 1 commit into from
Mar 10, 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
10 changes: 5 additions & 5 deletions src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ArrayViewInterface } from "./types";
* with a subset of elements from the original array or ArrayView.
*
* @template T
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
* @param {boolean} [readonly] - Optional flag to indicate whether the view should be readonly.
* @returns {ArrayView<T>} The created ArrayView instance.
*
Expand Down Expand Up @@ -61,7 +61,7 @@ export function slice(slice: string | Array<number | undefined> | Slice): SliceS
*
* This function allows you to create a selector that masks elements based on a boolean mask array.
*
* @param {Array<boolean> | ArrayView<boolean>} mask - The boolean mask array or ArrayView to create the selector from.
* @param {Array<boolean> | ArrayViewInterface<boolean>} mask - The boolean mask array or ArrayView to create the selector from.
*
* @returns {MaskSelector} The created MaskSelector instance.
*
Expand All @@ -73,7 +73,7 @@ export function slice(slice: string | Array<number | undefined> | Slice): SliceS
* console.log(filteredView);
* // [1, 3, 4]
*/
export function mask(mask: Array<boolean> | ArrayView<boolean>): MaskSelector {
export function mask(mask: Array<boolean> | ArrayViewInterface<boolean>): MaskSelector {
return new MaskSelector(mask);
}

Expand All @@ -82,7 +82,7 @@ export function mask(mask: Array<boolean> | ArrayView<boolean>): MaskSelector {
*
* This function allows you to create a selector for specifying a list of indexes to include in the selection.
*
* @param {Array<number> | ArrayView<number>} indexes - The array of indexes or IndexList to create the selector from.
* @param {Array<number> | ArrayViewInterface<number>} indexes - The array of indexes or IndexList to create the selector from.
*
* @returns {IndexListSelector} The created IndexListSelector instance.
*
Expand All @@ -94,6 +94,6 @@ export function mask(mask: Array<boolean> | ArrayView<boolean>): MaskSelector {
* console.log(filteredView);
* // [1, 3, 5]
*/
export function select(indexes: Array<number> | ArrayView<number>): IndexListSelector {
export function select(indexes: Array<number> | ArrayViewInterface<number>): IndexListSelector {
return new IndexListSelector(indexes);
}
22 changes: 11 additions & 11 deletions src/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ArrayMaskView, ArrayIndexListView, ArraySliceView, ArrayView } from "./views";
import { Slice } from "./structs";
import { ArraySelectorInterface } from "./types";
import { ArraySelectorInterface, ArrayViewInterface } from "./types";

/**
* Represents an index list selector that selects elements based on the provided array of indexes.
Expand All @@ -16,9 +16,9 @@ export class IndexListSelector implements ArraySelectorInterface {
/**
* Creates a new IndexListSelector instance with the provided array of indexes.
*
* @param {Array<number> | ArrayView<number>} value - The array of indexes or array view containing indexes.
* @param {Array<number> | ArrayViewInterface<number>} value - The array of indexes or array view containing indexes.
*/
constructor(value: Array<number> | ArrayView<number>) {
constructor(value: Array<number> | ArrayViewInterface<number>) {
this.value = value instanceof Array ? value : value.toArray();
}

Expand All @@ -27,12 +27,12 @@ export class IndexListSelector implements ArraySelectorInterface {
*
* @template T - The type of elements in the source array view.
*
* @param {ArrayView<T>} source - The source array view to select elements from.
* @param {ArrayViewInterface<T>} source - The source array view to select elements from.
* @param {boolean} [readonly] - Whether the selection should be read-only.
*
* @returns {ArrayIndexListView<T>} The view containing the selected elements.
*/
public select<T>(source: ArrayView<T>, readonly?: boolean): ArrayIndexListView<T> {
public select<T>(source: ArrayViewInterface<T>, readonly?: boolean): ArrayIndexListView<T> {
return new ArrayIndexListView<T>(source, { indexes: this.value, readonly: readonly ?? source.readonly });
}
}
Expand All @@ -51,9 +51,9 @@ export class MaskSelector implements ArraySelectorInterface {
/**
* Creates a new MaskSelector instance with the provided array of boolean mask values.
*
* @param {Array<boolean> | ArrayView<boolean>} value - The array or array view of boolean mask values.
* @param {Array<boolean> | ArrayViewInterface<boolean>} value - The array or array view of boolean mask values.
*/
constructor(value: Array<boolean> | ArrayView<boolean>) {
constructor(value: Array<boolean> | ArrayViewInterface<boolean>) {
this.value = value instanceof Array ? value : value.toArray();
}

Expand All @@ -62,12 +62,12 @@ export class MaskSelector implements ArraySelectorInterface {
*
* @template T - The type of elements in the source array view.
*
* @param {ArrayView<T>} source - The source array to select elements from.
* @param {ArrayViewInterface<T>} source - The source array to select elements from.
* @param {boolean} [readonly] - Whether the selection should be read-only.
*
* @returns {ArrayMaskView<T>} The view containing the selected elements.
*/
public select<T>(source: ArrayView<T>, readonly?: boolean): ArrayMaskView<T> {
public select<T>(source: ArrayViewInterface<T>, readonly?: boolean): ArrayMaskView<T> {
return new ArrayMaskView<T>(source, { mask: this.value, readonly: readonly ?? source.readonly });
}
}
Expand Down Expand Up @@ -95,12 +95,12 @@ export class SliceSelector extends Slice implements ArraySelectorInterface {
*
* @template T - The type of elements in the source array.
*
* @param {ArrayView<T>} source - The source array to select elements from.
* @param {ArrayViewInterface<T>} source - The source array to select elements from.
* @param {boolean} [readonly] - Whether the selection should be read-only.
*
* @returns {ArraySliceView<T>} The view containing the selected elements.
*/
public select<T>(source: ArrayView<T>, readonly?: boolean): ArraySliceView<T> {
public select<T>(source: ArrayViewInterface<T>, readonly?: boolean): ArraySliceView<T> {
return new ArraySliceView<T>(source, { slice: this, readonly: readonly ?? source.readonly });
}
}
6 changes: 3 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ export interface ArrayViewInterface<T> {
/**
* Sets new values for the elements in the view.
*
* @param {Array<T> | ArrayViewInterface<T>} newValues - The new values to set.
* @param {Array<T> | ArrayViewInterface<T> | T} newValue - The new values to set.
*
* @returns {ArrayViewInterface<T>} this view.
*/
set(newValues: Array<T> | ArrayViewInterface<T>): ArrayViewInterface<T>;
set(newValue: Array<T> | ArrayViewInterface<T> | T): ArrayViewInterface<T>;

/**
* Returns an iterator for the elements in the view.
Expand Down Expand Up @@ -128,5 +128,5 @@ export interface ArraySelectorInterface {
* @template T - The type of elements in the array.
*/
export type SliceableArray<T> = Array<T> & {
[index: string]: Array<T>
[index: string]: Array<T>;
}
4 changes: 4 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ export function normalizeIndex(index: number, containerLength: number, throwErro
}
return index < 0 ? containerLength + index : index;
}

export function isCountable(target: any): boolean {
return target.length !== undefined;
}
34 changes: 23 additions & 11 deletions src/views.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MaskSelector, SliceSelector } from "./selectors";
import { normalizeIndex } from "./utils";
import { isCountable, normalizeIndex } from "./utils";
import { KeyError, LengthError, ReadonlyError } from "./excpetions";
import { NormalizedSlice, Slice } from "./structs";
import type { ArrayViewInterface, ArraySelectorInterface, SliceableArray } from "./types";
Expand Down Expand Up @@ -57,7 +57,7 @@ export class ArrayView<T> implements ArrayViewInterface<T> {
/**
* Constructs a new ArrayView instance based on the provided source array or ArrayView.
*
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
* @param {object} options - Options for configuring the view.
* @param {boolean} [options.readonly=false] - Optional flag to indicate whether the view should be readonly.
*
Expand All @@ -70,7 +70,7 @@ export class ArrayView<T> implements ArrayViewInterface<T> {
const loc = Array.isArray(source) ? source : source.loc;
this.source = Array.isArray(source) ? source : source.source;
this.parentView = Array.isArray(source) ? undefined : source;
this.readonly = readonly ?? ((source instanceof ArrayView) ? (source as ArrayView<T>).readonly : false);
this.readonly = readonly ?? (Array.isArray(source) ? false : (source as ArrayViewInterface<T>).readonly);

if ((source instanceof ArrayView) && source.readonly && !this.readonly) {
throw new ReadonlyError("Cannot create non-readonly view for readonly source.");
Expand Down Expand Up @@ -156,7 +156,10 @@ export class ArrayView<T> implements ArrayViewInterface<T> {
}

/** @inheritDoc */
public applyWith<U>(data: Array<U> | ArrayView<U>, mapper: (lhs: T, rhs: U, index: number) => T): ArrayView<T> {
public applyWith<U>(
data: Array<U> | ArrayViewInterface<U>,
mapper: (lhs: T, rhs: U, index: number) => T,
): ArrayView<T> {
if (data.length !== this.length) {
throw new LengthError(`Length of values array not equal to view length (${data.length} != ${this.length}).`);
}
Expand All @@ -171,7 +174,16 @@ export class ArrayView<T> implements ArrayViewInterface<T> {
}

/** @inheritDoc */
public set(newValues: Array<T> | ArrayView<T>): ArrayView<T> {
public set(newValue: Array<T> | ArrayViewInterface<T> | T): ArrayView<T> {
if (!isCountable(newValue)) {
for (let i = 0; i < this.length; ++i) {
this.loc[i] = newValue as T;
}
return this;
}

const newValues = newValue as Array<T> | ArrayViewInterface<T>;

if (newValues.length !== this.length) {
throw new LengthError(`Length of values array not equal to view length (${newValues.length} != ${this.length}).`);
}
Expand Down Expand Up @@ -236,15 +248,15 @@ export class ArrayIndexListView<T> extends ArrayView<T> {
/**
* Constructs a new ArrayIndexListView instance with the specified source array or ArrayView and indexes array.
*
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
* @param {object} options - Options for configuring the view.
* @param {number[]} options.indexes - The indexes array specifying the indexes of elements in the source array.
* @param {boolean} [options.readonly] - Optional flag to indicate whether the view should be readonly.
*
* @constructor
*/
constructor(
source: Array<T> | ArrayView<T>,
source: Array<T> | ArrayViewInterface<T>,
{
indexes,
readonly,
Expand Down Expand Up @@ -297,15 +309,15 @@ export class ArrayMaskView<T> extends ArrayIndexListView<T> {
/**
* Constructs a new ArrayMaskView instance with the specified source array or ArrayView and boolean mask.
*
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
* @param {object} options - Options for configuring the view.
* @param {boolean[]} options.mask - The boolean mask for including or excluding elements from the source array.
* @param {boolean} [options.readonly] - Optional flag to indicate whether the view should be readonly.
*
* @constructor
*/
constructor(
source: Array<T> | ArrayView<T>,
source: Array<T> | ArrayViewInterface<T>,
{
mask,
readonly,
Expand Down Expand Up @@ -343,15 +355,15 @@ export class ArraySliceView<T> extends ArrayView<T> {
/**
* Constructs a new ArraySliceView instance with the specified source array or ArrayView and slice range.
*
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
* @param {object} options - Options for configuring the view.
* @param {Slice} options.slice - The slice range specifying the subset of elements to include in the view.
* @param {boolean} [options.readonly] - Optional flag to indicate whether the view should be readonly.
*
* @constructor
*/
constructor(
source: Array<T> | ArrayView<T>,
source: Array<T> | ArrayViewInterface<T>,
{
slice,
readonly,
Expand Down
14 changes: 12 additions & 2 deletions tests/views/array-view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ describe.each([
(
source: Array<number>,
viewGetter: (source: Array<number>) => ArrayView<number>,
toWrite: Array<number>,
toWrite: Array<number> | number,
expected: Array<number>,
) => {
it("", () => {
Expand All @@ -339,14 +339,15 @@ describe.each([
(
source: Array<number>,
viewGetter: (source: Array<number>) => ArrayView<number>,
toWrite: Array<number>,
toWrite: Array<number> | number,
expected: Array<number>,
) => {
it("", () => {
// Given
const v = viewGetter(source);

// When
// @ts-ignore
v.loc[':'] = toWrite;

// Then
Expand Down Expand Up @@ -439,6 +440,15 @@ function dataProviderForCombineWrite(): Array<unknown> {
[11, 99],
[11, 2, 3, 4, 5, 6, 7, 8, 99, 10],
],
[
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
(source: Array<number>) => view(source)
.subview(slice(new Slice(undefined, undefined, 2)))
.subview(slice('::2'))
.subview('::2'),
111,
[111, 2, 3, 4, 5, 6, 7, 8, 111, 10],
],
];
}

Expand Down
Loading