feat: Implement the [Symbol.iterator], forEach, filter, map, and reduce methods for Graph, specifically targeting the nodes. fix: type error fixed

This commit is contained in:
Revone 2023-11-27 11:24:23 +08:00
parent a71b223226
commit 20550fb718
8 changed files with 94 additions and 7 deletions

View file

@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)
## [v1.47.7](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
## [v1.47.8](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
### Changes

View file

@ -1,6 +1,6 @@
{
"name": "data-structure-typed",
"version": "1.47.7",
"version": "1.47.8",
"description": "Data Structures of Javascript & TypeScript. Heap, Binary Tree, RedBlack Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack.",
"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",

View file

@ -1159,6 +1159,52 @@ export abstract class AbstractGraph<
return this.tarjan(false, true, false, false).bridges;
}
* [Symbol.iterator](): Iterator<[VertexKey, V | undefined]> {
for (const vertex of this._vertices.values()) {
yield [vertex.key, vertex.value];
}
}
forEach(callback: (entry: [VertexKey, V | undefined], index: number, map: Map<VertexKey, VO>) => void): void {
let index = 0;
for (const vertex of this) {
callback(vertex, index, this._vertices);
index++;
}
}
filter(predicate: (entry: [VertexKey, V | undefined], index: number, map: Map<VertexKey, VO>) => boolean): [VertexKey, V | undefined][] {
const filtered: [VertexKey, V | undefined][] = [];
let index = 0;
for (const entry of this) {
if (predicate(entry, index, this._vertices)) {
filtered.push(entry);
}
index++;
}
return filtered;
}
map<T>(callback: (entry: [VertexKey, V | undefined], index: number, map: Map<VertexKey, VO>) => T): T[] {
const mapped: T[] = [];
let index = 0;
for (const entry of this) {
mapped.push(callback(entry, index, this._vertices));
index++;
}
return mapped;
}
reduce<T>(callback: (accumulator: T, entry: [VertexKey, V | undefined], index: number, map: Map<VertexKey, VO>) => T, initialValue: T): T {
let accumulator: T = initialValue;
let index = 0;
for (const entry of this) {
accumulator = callback(accumulator, entry, index, this._vertices);
index++;
}
return accumulator;
}
protected abstract _addEdgeOnly(edge: EO): boolean;
protected _addVertexOnly(newVertex: VO): boolean {

View file

@ -87,7 +87,7 @@ export class DirectedGraph<
* @returns a new instance of a DirectedVertex object, casted as type VO.
*/
createVertex(key: VertexKey, value?: V): VO {
return new DirectedVertex(key, value ?? key) as VO;
return new DirectedVertex(key, value) as VO;
}
/**

View file

@ -349,7 +349,7 @@
// 1 _4 6 _9
// / /
// 3 8
const trie2 = new Trie(orgStrArr);
trie2.print(); // ['trie', 'trial', 'triangle', 'trick', 'trip', 'tree', 'trend', 'track', 'trace', 'transmit']
@ -367,7 +367,7 @@
// 0 2 _5_ 8_
// / \ \
// 4 6 9
} catch (e) {
console.error(e);
}

View file

@ -57,7 +57,7 @@ suite
})
.add(`${LINEAR.toLocaleString()} insertBefore`, () => {
const doublyList = new DoublyLinkedList<number>();
let midNode: DoublyLinkedListNode | null = null;
let midNode: DoublyLinkedListNode | undefined;
const midIndex = Math.floor(LINEAR / 2);
for (let i = 0; i < LINEAR; i++) {
doublyList.push(i);

View file

@ -19,7 +19,7 @@ suite
})
.add(`${TEN_THOUSAND.toLocaleString()} insertBefore`, () => {
const singlyList = new SinglyLinkedList<number>();
let midSinglyNode: SinglyLinkedListNode | null = null;
let midSinglyNode: SinglyLinkedListNode | undefined;
const midIndex = Math.floor(TEN_THOUSAND / 2);
for (let i = 0; i < TEN_THOUSAND; i++) {
singlyList.push(i);

View file

@ -595,3 +595,44 @@ describe('cycles, strongly connected components, bridges, articular points in Di
expect(dfnMap.size).toBe(8);
expect(lowMap.size).toBe(8);
});
describe('DirectedGraph iterative Methods', () => {
let graph: DirectedGraph<string>;
let vertices: string[];
beforeEach(() => {
graph = new DirectedGraph();
vertices = ['A', 'B', 'C', 'D'];
vertices.forEach(vertex => graph.addVertex(vertex));
});
test('[Symbol.iterator] should iterate over all vertices', () => {
const iteratedVertices = [];
for (const vertex of graph) {
iteratedVertices.push(vertex[0]);
}
expect(iteratedVertices).toEqual(vertices);
});
test('forEach should apply a function to each vertex', () => {
const result: VertexKey[] = [];
graph.forEach(vertex => result.push(vertex[0]));
expect(result).toEqual(vertices);
});
test('filter should return vertices that satisfy the condition', () => {
const filtered = graph.filter(vertex => vertex[0] === 'A' || vertex[0] === 'B');
expect(filtered).toEqual([["A", undefined], ["B", undefined]]);
});
test('map should apply a function to each vertex and return a new array', () => {
const mapped = graph.map(vertex => vertex[0] + '_mapped');
expect(mapped).toEqual(vertices.map(v => v + '_mapped'));
});
test('reduce should accumulate a value based on each vertex', () => {
const concatenated = graph.reduce((acc, vertex) => acc + vertex[0], '');
expect(concatenated).toBe(vertices.join(''));
});
});