Skip to content

Commit ff798cb

Browse files
committed
Refactor, type fixes.
1 parent 80a2bdf commit ff798cb

File tree

6 files changed

+58
-32
lines changed

6 files changed

+58
-32
lines changed

src/functions.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ArrayViewInterface } from "./types";
1010
* with a subset of elements from the original array or ArrayView.
1111
*
1212
* @template T
13-
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
13+
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
1414
* @param {boolean} [readonly] - Optional flag to indicate whether the view should be readonly.
1515
* @returns {ArrayView<T>} The created ArrayView instance.
1616
*
@@ -61,7 +61,7 @@ export function slice(slice: string | Array<number | undefined> | Slice): SliceS
6161
*
6262
* This function allows you to create a selector that masks elements based on a boolean mask array.
6363
*
64-
* @param {Array<boolean> | ArrayView<boolean>} mask - The boolean mask array or ArrayView to create the selector from.
64+
* @param {Array<boolean> | ArrayViewInterface<boolean>} mask - The boolean mask array or ArrayView to create the selector from.
6565
*
6666
* @returns {MaskSelector} The created MaskSelector instance.
6767
*
@@ -73,7 +73,7 @@ export function slice(slice: string | Array<number | undefined> | Slice): SliceS
7373
* console.log(filteredView);
7474
* // [1, 3, 4]
7575
*/
76-
export function mask(mask: Array<boolean> | ArrayView<boolean>): MaskSelector {
76+
export function mask(mask: Array<boolean> | ArrayViewInterface<boolean>): MaskSelector {
7777
return new MaskSelector(mask);
7878
}
7979

@@ -82,7 +82,7 @@ export function mask(mask: Array<boolean> | ArrayView<boolean>): MaskSelector {
8282
*
8383
* This function allows you to create a selector for specifying a list of indexes to include in the selection.
8484
*
85-
* @param {Array<number> | ArrayView<number>} indexes - The array of indexes or IndexList to create the selector from.
85+
* @param {Array<number> | ArrayViewInterface<number>} indexes - The array of indexes or IndexList to create the selector from.
8686
*
8787
* @returns {IndexListSelector} The created IndexListSelector instance.
8888
*
@@ -94,6 +94,6 @@ export function mask(mask: Array<boolean> | ArrayView<boolean>): MaskSelector {
9494
* console.log(filteredView);
9595
* // [1, 3, 5]
9696
*/
97-
export function select(indexes: Array<number> | ArrayView<number>): IndexListSelector {
97+
export function select(indexes: Array<number> | ArrayViewInterface<number>): IndexListSelector {
9898
return new IndexListSelector(indexes);
9999
}

src/selectors.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ArrayMaskView, ArrayIndexListView, ArraySliceView, ArrayView } from "./views";
22
import { Slice } from "./structs";
3-
import { ArraySelectorInterface } from "./types";
3+
import { ArraySelectorInterface, ArrayViewInterface } from "./types";
44

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

@@ -27,12 +27,12 @@ export class IndexListSelector implements ArraySelectorInterface {
2727
*
2828
* @template T - The type of elements in the source array view.
2929
*
30-
* @param {ArrayView<T>} source - The source array view to select elements from.
30+
* @param {ArrayViewInterface<T>} source - The source array view to select elements from.
3131
* @param {boolean} [readonly] - Whether the selection should be read-only.
3232
*
3333
* @returns {ArrayIndexListView<T>} The view containing the selected elements.
3434
*/
35-
public select<T>(source: ArrayView<T>, readonly?: boolean): ArrayIndexListView<T> {
35+
public select<T>(source: ArrayViewInterface<T>, readonly?: boolean): ArrayIndexListView<T> {
3636
return new ArrayIndexListView<T>(source, { indexes: this.value, readonly: readonly ?? source.readonly });
3737
}
3838
}
@@ -51,9 +51,9 @@ export class MaskSelector implements ArraySelectorInterface {
5151
/**
5252
* Creates a new MaskSelector instance with the provided array of boolean mask values.
5353
*
54-
* @param {Array<boolean> | ArrayView<boolean>} value - The array or array view of boolean mask values.
54+
* @param {Array<boolean> | ArrayViewInterface<boolean>} value - The array or array view of boolean mask values.
5555
*/
56-
constructor(value: Array<boolean> | ArrayView<boolean>) {
56+
constructor(value: Array<boolean> | ArrayViewInterface<boolean>) {
5757
this.value = value instanceof Array ? value : value.toArray();
5858
}
5959

@@ -62,12 +62,12 @@ export class MaskSelector implements ArraySelectorInterface {
6262
*
6363
* @template T - The type of elements in the source array view.
6464
*
65-
* @param {ArrayView<T>} source - The source array to select elements from.
65+
* @param {ArrayViewInterface<T>} source - The source array to select elements from.
6666
* @param {boolean} [readonly] - Whether the selection should be read-only.
6767
*
6868
* @returns {ArrayMaskView<T>} The view containing the selected elements.
6969
*/
70-
public select<T>(source: ArrayView<T>, readonly?: boolean): ArrayMaskView<T> {
70+
public select<T>(source: ArrayViewInterface<T>, readonly?: boolean): ArrayMaskView<T> {
7171
return new ArrayMaskView<T>(source, { mask: this.value, readonly: readonly ?? source.readonly });
7272
}
7373
}
@@ -95,12 +95,12 @@ export class SliceSelector extends Slice implements ArraySelectorInterface {
9595
*
9696
* @template T - The type of elements in the source array.
9797
*
98-
* @param {ArrayView<T>} source - The source array to select elements from.
98+
* @param {ArrayViewInterface<T>} source - The source array to select elements from.
9999
* @param {boolean} [readonly] - Whether the selection should be read-only.
100100
*
101101
* @returns {ArraySliceView<T>} The view containing the selected elements.
102102
*/
103-
public select<T>(source: ArrayView<T>, readonly?: boolean): ArraySliceView<T> {
103+
public select<T>(source: ArrayViewInterface<T>, readonly?: boolean): ArraySliceView<T> {
104104
return new ArraySliceView<T>(source, { slice: this, readonly: readonly ?? source.readonly });
105105
}
106106
}

src/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ export interface ArrayViewInterface<T> {
9191
/**
9292
* Sets new values for the elements in the view.
9393
*
94-
* @param {Array<T> | ArrayViewInterface<T>} newValues - The new values to set.
94+
* @param {Array<T> | ArrayViewInterface<T> | T} newValue - The new values to set.
9595
*
9696
* @returns {ArrayViewInterface<T>} this view.
9797
*/
98-
set(newValues: Array<T> | ArrayViewInterface<T>): ArrayViewInterface<T>;
98+
set(newValue: Array<T> | ArrayViewInterface<T> | T): ArrayViewInterface<T>;
9999

100100
/**
101101
* Returns an iterator for the elements in the view.
@@ -128,5 +128,5 @@ export interface ArraySelectorInterface {
128128
* @template T - The type of elements in the array.
129129
*/
130130
export type SliceableArray<T> = Array<T> & {
131-
[index: string]: Array<T>
131+
[index: string]: Array<T>;
132132
}

src/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ export function normalizeIndex(index: number, containerLength: number, throwErro
1717
}
1818
return index < 0 ? containerLength + index : index;
1919
}
20+
21+
export function isCountable(target: any): boolean {
22+
return target.length !== undefined;
23+
}

src/views.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { MaskSelector, SliceSelector } from "./selectors";
2-
import { normalizeIndex } from "./utils";
2+
import { isCountable, normalizeIndex } from "./utils";
33
import { KeyError, LengthError, ReadonlyError } from "./excpetions";
44
import { NormalizedSlice, Slice } from "./structs";
55
import type { ArrayViewInterface, ArraySelectorInterface, SliceableArray } from "./types";
@@ -57,7 +57,7 @@ export class ArrayView<T> implements ArrayViewInterface<T> {
5757
/**
5858
* Constructs a new ArrayView instance based on the provided source array or ArrayView.
5959
*
60-
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
60+
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
6161
* @param {object} options - Options for configuring the view.
6262
* @param {boolean} [options.readonly=false] - Optional flag to indicate whether the view should be readonly.
6363
*
@@ -70,7 +70,7 @@ export class ArrayView<T> implements ArrayViewInterface<T> {
7070
const loc = Array.isArray(source) ? source : source.loc;
7171
this.source = Array.isArray(source) ? source : source.source;
7272
this.parentView = Array.isArray(source) ? undefined : source;
73-
this.readonly = readonly ?? ((source instanceof ArrayView) ? (source as ArrayView<T>).readonly : false);
73+
this.readonly = readonly ?? (Array.isArray(source) ? false : (source as ArrayViewInterface<T>).readonly);
7474

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

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

173176
/** @inheritDoc */
174-
public set(newValues: Array<T> | ArrayView<T>): ArrayView<T> {
177+
public set(newValue: Array<T> | ArrayViewInterface<T> | T): ArrayView<T> {
178+
if (!isCountable(newValue)) {
179+
for (let i = 0; i < this.length; ++i) {
180+
this.loc[i] = newValue as T;
181+
}
182+
return this;
183+
}
184+
185+
const newValues = newValue as Array<T> | ArrayViewInterface<T>;
186+
175187
if (newValues.length !== this.length) {
176188
throw new LengthError(`Length of values array not equal to view length (${newValues.length} != ${this.length}).`);
177189
}
@@ -236,15 +248,15 @@ export class ArrayIndexListView<T> extends ArrayView<T> {
236248
/**
237249
* Constructs a new ArrayIndexListView instance with the specified source array or ArrayView and indexes array.
238250
*
239-
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
251+
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
240252
* @param {object} options - Options for configuring the view.
241253
* @param {number[]} options.indexes - The indexes array specifying the indexes of elements in the source array.
242254
* @param {boolean} [options.readonly] - Optional flag to indicate whether the view should be readonly.
243255
*
244256
* @constructor
245257
*/
246258
constructor(
247-
source: Array<T> | ArrayView<T>,
259+
source: Array<T> | ArrayViewInterface<T>,
248260
{
249261
indexes,
250262
readonly,
@@ -297,15 +309,15 @@ export class ArrayMaskView<T> extends ArrayIndexListView<T> {
297309
/**
298310
* Constructs a new ArrayMaskView instance with the specified source array or ArrayView and boolean mask.
299311
*
300-
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
312+
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
301313
* @param {object} options - Options for configuring the view.
302314
* @param {boolean[]} options.mask - The boolean mask for including or excluding elements from the source array.
303315
* @param {boolean} [options.readonly] - Optional flag to indicate whether the view should be readonly.
304316
*
305317
* @constructor
306318
*/
307319
constructor(
308-
source: Array<T> | ArrayView<T>,
320+
source: Array<T> | ArrayViewInterface<T>,
309321
{
310322
mask,
311323
readonly,
@@ -343,15 +355,15 @@ export class ArraySliceView<T> extends ArrayView<T> {
343355
/**
344356
* Constructs a new ArraySliceView instance with the specified source array or ArrayView and slice range.
345357
*
346-
* @param {Array<T> | ArrayView<T>} source - The source array or ArrayView to create a view from.
358+
* @param {Array<T> | ArrayViewInterface<T>} source - The source array or ArrayView to create a view from.
347359
* @param {object} options - Options for configuring the view.
348360
* @param {Slice} options.slice - The slice range specifying the subset of elements to include in the view.
349361
* @param {boolean} [options.readonly] - Optional flag to indicate whether the view should be readonly.
350362
*
351363
* @constructor
352364
*/
353365
constructor(
354-
source: Array<T> | ArrayView<T>,
366+
source: Array<T> | ArrayViewInterface<T>,
355367
{
356368
slice,
357369
readonly,

tests/views/array-view.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ describe.each([
316316
(
317317
source: Array<number>,
318318
viewGetter: (source: Array<number>) => ArrayView<number>,
319-
toWrite: Array<number>,
319+
toWrite: Array<number> | number,
320320
expected: Array<number>,
321321
) => {
322322
it("", () => {
@@ -339,14 +339,15 @@ describe.each([
339339
(
340340
source: Array<number>,
341341
viewGetter: (source: Array<number>) => ArrayView<number>,
342-
toWrite: Array<number>,
342+
toWrite: Array<number> | number,
343343
expected: Array<number>,
344344
) => {
345345
it("", () => {
346346
// Given
347347
const v = viewGetter(source);
348348

349349
// When
350+
// @ts-ignore
350351
v.loc[':'] = toWrite;
351352

352353
// Then
@@ -439,6 +440,15 @@ function dataProviderForCombineWrite(): Array<unknown> {
439440
[11, 99],
440441
[11, 2, 3, 4, 5, 6, 7, 8, 99, 10],
441442
],
443+
[
444+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
445+
(source: Array<number>) => view(source)
446+
.subview(slice(new Slice(undefined, undefined, 2)))
447+
.subview(slice('::2'))
448+
.subview('::2'),
449+
111,
450+
[111, 2, 3, 4, 5, 6, 7, 8, 111, 10],
451+
],
442452
];
443453
}
444454

0 commit comments

Comments
 (0)