TypeScriptによるArrayベースのADT Listの実装
34918 ワード
以前Javaで作成した配列ベースのADTリストをTypescriptで書き換えた.
interface List<T> {
readonly size: number;
isEmpty(): boolean;
isFull(): boolean;
add(item: T, index: number): ResultState<T>;
remove(index: number): ResultState<T>;
removeAll(): void;
get(index: number): ResultState<T>;
find(item: T): ResultState<T>;
}
まず,インタフェースは操作とともにsizeというデータフローを定義する.インタフェースタイプのクラスオブジェクトを作成した後、外部アクセス時に変更できないためreadonlyが追加されました.また、add、remove、get、findメソッドを呼び出すと、発生する可能性のあるエラーを処理するために、成功または失敗に関する情報を含むResultStateが返されます.type SuccessState<T> = {
state: 'success';
array: Array<T>;
element?: T;
index?: number;
};
type FailureReason =
| 'index out of range'
| 'already full list'
| 'empty list'
| 'invalid value';
type FailureState = {
state: 'fail';
reason: FailureReason;
};
type ResultState<T> = SuccessState<T> | FailureState;
SuccesStateとFailuresStateはResultStateとして定義され、State Propertyと区別できる区分単位である.FailureReasonはString Literal TypeのUnion Typeとして定義されています.class ListImpl<T> implements List<T> {
private _size: number = 0;
private readonly MAX_LENGTH = 5;
private array: Array<T> = new Array();
private get RESULT_ARRAY(): SuccessState<T> {
return {
state: 'success',
array: this.array,
};
}
private readonly INDEX_OUT_OF_RANGE: FailureState = {
state: 'fail',
reason: 'index out of range',
};
private readonly FULL_LIST: FailureState = {
state: 'fail',
reason: 'already full list',
};
private readonly EMPTY_LIST: FailureState = {
state: 'fail',
reason: 'empty list',
};
private readonly INVALID_VALUE: FailureState = {
state: 'fail',
reason: 'invalid value',
};
get size() {
return this._size;
}
isEmpty(): boolean {
if (this._size === 0) return true;
else return false;
}
isFull(): boolean {
if (this._size === this.MAX_LENGTH) return true;
return false;
}
add(item: T, index: number): ResultState<T> {
if (this.isFull()) {
return this.FULL_LIST;
}
if (index < 0 || index > this.size) {
return this.INDEX_OUT_OF_RANGE;
}
for (let j = this.size; j > index; j--) {
this.array[j] = this.array[j - 1];
}
this.array[index] = item;
this._size++;
return this.RESULT_ARRAY;
}
remove(index: number): ResultState<T> {
if (this.isEmpty()) {
return this.EMPTY_LIST;
}
if (index < 0 || index >= this.size) {
return this.INDEX_OUT_OF_RANGE;
}
for (let j = index; j < this.size; j++) {
this.array[j] = this.array[j + 1];
}
this._size--;
return this.RESULT_ARRAY;
}
removeAll(): void {
this.array = new Array();
this._size = 0;
}
get(index: number): ResultState<T> {
if (this.isEmpty()) {
return this.EMPTY_LIST;
}
if (index < 0 || index >= this.size) {
return this.INDEX_OUT_OF_RANGE;
}
return {
...this.RESULT_ARRAY,
element: this.array[index],
};
}
find(item: T): ResultState<T> {
if (this.isEmpty()) {
return this.EMPTY_LIST;
}
for (let j = 0; j < this._size; j++) {
if (this.array[j] === item) {
return {
...this.RESULT_ARRAY,
index: j,
};
}
}
return this.INVALID_VALUE;
}
}
インタフェースでreadonly propertyとして定義されているsizeの場合、クラス内でreadonly propertyとして定義されている場合、クラス内ではpropertyを変更できないため、変更可能なプライベートpropertyの下線を持つsizeが宣言され、sizeを返すcustom getterが定義されます.また、各メソッドの内部には、成功または失敗(無効なインデックス範囲、フルリスト、空のリスト、無効な値)が定義されています.つまり、上記で定義した各タイプのオブジェクト構成が返されます.これにより、コードの再利用性が向上します.const list: List<string> = new ListImpl<string>();
type Fruit = [name: string, index: number];
const fruits: Fruit[] = [['Apple', 0], ['Banana', 1], ['Orange', 2], ['Peach', 1]];
for (let i=0; i<fruits.length; i++) {
const [name, index] = fruits[i];
const result = list.add(name, index);
if (result.state == "success") {
console.log(result.array);
} else {
console.log(result.reason);
}
}
const result2 = list.remove(4);
if (result2.state == "success") {
console.log(result2.array);
} else {
console.log(result2.reason);
}
const result3 = list.get(3);
if (result3.state == "success") {
console.log(result3.element);
} else {
console.log(result3.reason);
}
const result4 = list.find('Peach');
if (result4.state == "success") {
console.log(result4.index);
} else {
console.log(result4.reason);
}
1つのパターンをFruitとして定義し、これらのパターンの配列を含むオブジェクトを定義します.これにより、add、remove、get、findがそれぞれ返すオブジェクトの状態が「成功」か「失敗」かで、結果の出力が異なる.Reference
この問題について(TypeScriptによるArrayベースのADT Listの実装), 我々は、より多くの情報をここで見つけました https://velog.io/@sorikiki/Typescript로-Array-based-ADT-List-구현하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol