Skip to content
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
2 changes: 1 addition & 1 deletion DEVELOPMENT_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ This document outlines possible improvements and future developments for the `TS

- **Performance Benchmarks**: Add benchmarks to evaluate and optimize the performance of the data structures.
- **Browser Support**: Provide build targets that work in browser environments, possibly using bundlers like Rollup or Webpack.
- **Typed Iterators**: Implement iterator interfaces for data structures to integrate seamlessly with ES6 iteration protocols.
- **Typed Iterators**: Implement iterator interfaces for data structures to integrate seamlessly with ES6 iteration protocols. *(Implemented)*

15 changes: 15 additions & 0 deletions src/AVLTree/AVLTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ export class AVLTree<T> {
return result;
}

/**
* Enables iteration over the tree values in-order.
*/
public *[Symbol.iterator](): IterableIterator<T> {
function* traverse(node: AVLTreeNode<T> | null): IterableIterator<T> {
if (node === null) {
return;
}
yield* traverse(node.getLeft());
yield node.getValue();
yield* traverse(node.getRight());
}
yield* traverse(this.root);
}

private insertNode(node: AVLTreeNode<T> | null, value: T): AVLTreeNode<T> {
if (node === null) {
return new AVLTreeNode<T>(value);
Expand Down
15 changes: 15 additions & 0 deletions src/BinaryTree/BinaryTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,21 @@ export class BinaryTree<T> {
return this.inOrderTraversal();
}

/**
* Enables iteration over tree values in-order.
*/
public *[Symbol.iterator](): IterableIterator<T> {
function* traverse(node: BinaryTreeNode<T> | null): IterableIterator<T> {
if (node === null || node.getValue() === null) {
return;
}
yield* traverse(node.getLeft());
yield node.getValue();
yield* traverse(node.getRight());
}
yield* traverse(this._root);
}

/**
* Returns a string representation of the tree.
* @return string
Expand Down
9 changes: 9 additions & 0 deletions src/Dictionary/Dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,15 @@ export class Dictionary<T> {
});
}

/**
* Enables iteration over key-value pairs in insertion order.
*/
public *[Symbol.iterator](): IterableIterator<{ key: string; value: T }> {
for (const key of this.keys()) {
yield { key, value: this.items[key] };
}
}

// =========================================================================================================================================================
// Private methods
// =========================================================================================================================================================
Expand Down
9 changes: 9 additions & 0 deletions src/Graph/Graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,13 @@ export class Graph<T> {
}
return path;
}
/**
* Enables iteration over all vertices in the graph.
*/
public *[Symbol.iterator](): IterableIterator<T> {
for (const key of this.adjacency.keys()) {
yield key;
}
}

}
9 changes: 9 additions & 0 deletions src/HashMap/HashMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,14 @@ export class HashMap<K, V> {
public clear(): void {
this.map.clear();
}
/**
* Enables iteration over key-value pairs in insertion order.
*/
public *[Symbol.iterator](): IterableIterator<[K, V]> {
for (const entry of this.map.entries()) {
yield entry;
}
}


}
11 changes: 11 additions & 0 deletions src/List/DoubleLinkedList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ export class DoubleLinkedList<T> {
return result;
}

/**
* Enables iteration over the list using ES6 iteration protocols.
*/
public *[Symbol.iterator](): IterableIterator<T> {
let node = this._head;
while (node !== null) {
yield node.getValue();
node = node.getNext();
}
}

/**
* Inserts given value to the DoubleLinkedList and returns updated DoubleLinkedList.
* */
Expand Down
11 changes: 11 additions & 0 deletions src/List/LinkedList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ export class LinkedList<T> {
return result;
}

/**
* Enables iteration over the list using ES6 iteration protocols.
*/
public *[Symbol.iterator](): IterableIterator<T> {
let node = this._head;
while (node !== null) {
yield node.getValue();
node = node.getNext();
}
}

/**
* Inserts given value to the linkedList and returns updated LinkedList
* */
Expand Down
9 changes: 9 additions & 0 deletions src/PriorityQueue/PriorityQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ export class PriorityQueue<T> {
return this.heap.map(item => item.value);
}

/**
* Iterates over the queue values in heap order.
*/
public *[Symbol.iterator](): IterableIterator<T> {
for (const item of this.heap) {
yield item.value;
}
}

private bubbleUp(index: number): void {
const element = this.heap[index];
while (index > 0) {
Expand Down
9 changes: 9 additions & 0 deletions src/Queue/Queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ export class Queue<T> {
return this._store;
}

/**
* Enables iteration over queue values from front to back.
*/
public *[Symbol.iterator](): IterableIterator<T> {
for (const item of this._store) {
yield item;
}
}

// =========================================================================================================================================================
// Private methods
// =========================================================================================================================================================
Expand Down
9 changes: 9 additions & 0 deletions src/Stack/Stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ export class Stack<T> {
return this._store;
}

/**
* Enables iteration over stack values from bottom to top.
*/
public *[Symbol.iterator](): IterableIterator<T> {
for (const item of this._store) {
yield item;
}
}

// =========================================================================================================================================================
// Private methods
// =========================================================================================================================================================
Expand Down
15 changes: 15 additions & 0 deletions src/Tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,19 @@ export class Tree<T> {
node.getChildren().forEach(child => queue.push(child));
}
}

/**
* Enables iteration over the tree nodes in level order.
*/
public *[Symbol.iterator](): IterableIterator<T> {
if (this.root === null) {
return;
}
const queue: TreeNode<T>[] = [this.root];
while (queue.length > 0) {
const node = queue.shift()!;
yield node.getValue();
queue.push(...node.getChildren());
}
}
}
10 changes: 10 additions & 0 deletions tests/AVLTree/AVLTree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ describe('AVLTree', () => {
[4, 2, 6, 1, 3, 5, 7].forEach(v => tree.insert(v));
expect(tree.toArray()).to.deep.equal([1,2,3,4,5,6,7]);
});

it('should be iterable with for-of', () => {
const tree = new AVLTree<number>();
[3,1,4].forEach(v => tree.insert(v));
const result: number[] = [];
for (const v of tree) {
result.push(v);
}
expect(result).to.deep.equal([1,3,4]);
});
});
9 changes: 9 additions & 0 deletions tests/BinaryTree/BinaryTree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,15 @@ describe('BinaryTree', () => {

expect(tree.toArray()).to.deep.equal([3, 5, 8, 10, 15]);
});
it('should be iterable with for-of', () => {
const tree = new BinaryTree<number>();
[10, 5, 15].forEach(v => tree.insert(v));
const result: number[] = [];
for (const value of tree) {
result.push(value);
}
expect(result).to.deep.equal([5, 10, 15]);
});
});
});

Expand Down
13 changes: 13 additions & 0 deletions tests/Dictionary/Dictionary.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ describe('Dictionary', () => {
]);
});

it('should be iterable with for-of', () => {
dictionary.put('a', 1);
dictionary.put('b', 2);
const entries: { key: string; value: number }[] = [];
for (const item of dictionary) {
entries.push(item);
}
expect(entries).to.deep.equal([
{ key: 'a', value: 1 },
{ key: 'b', value: 2 },
]);
});

it('setValue()', () => {

dictionary.put('key1', 1);
Expand Down
10 changes: 10 additions & 0 deletions tests/Graph/Graph.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,14 @@ describe('Graph', () => {
const path = graph.shortestPath('A', 'C');
expect(path).to.deep.equal(['A', 'B', 'C']);
});

it('should be iterable with for-of', () => {
graph.addVertex('X');
graph.addVertex('Y');
const nodes: string[] = [];
for (const v of graph) {
nodes.push(v);
}
expect(new Set(nodes)).to.deep.equal(new Set(['X', 'Y']));
});
});
13 changes: 13 additions & 0 deletions tests/HashMap/HashMap.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,17 @@ describe('HashMap', () => {
expect(map.isEmpty()).to.be.true;
});
});

it('should be iterable with for-of', () => {
map.put('a', 1);
map.put('b', 2);
const entries: Array<[string, number]> = [];
for (const pair of map) {
entries.push(pair);
}
expect(entries).to.deep.include.members([
['a', 1],
['b', 2],
]);
});
});
13 changes: 13 additions & 0 deletions tests/List/DoubleLinkedList.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ describe('DoubleLinkedList', () => {

});

it('should be iterable with for-of', () => {
doubleLinkedList.append(1);
doubleLinkedList.append(2);
doubleLinkedList.append(3);
doubleLinkedList.append(4);

const collected: number[] = [];
for (const value of doubleLinkedList) {
collected.push(value);
}
expect(collected).to.deep.equal([1, 2, 3, 4]);
});

it('getLast', () => {
doubleLinkedList.append(1);
doubleLinkedList.append(2);
Expand Down
13 changes: 13 additions & 0 deletions tests/List/LinkedList.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ describe('LinkedList', () => {

});

it('should be iterable with for-of', () => {
linkedList.append(1);
linkedList.append(2);
linkedList.append(3);
linkedList.append(4);

const collected: number[] = [];
for (const value of linkedList) {
collected.push(value);
}
expect(collected).to.deep.equal([1, 2, 3, 4]);
});

it('getLast', () => {
linkedList.append(1);
linkedList.append(2);
Expand Down
12 changes: 12 additions & 0 deletions tests/PriorityQueue/PriorityQueue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,16 @@ describe('PriorityQueue', () => {
expect(queue.peek()).equal(null);
expect(queue.size()).equal(0);
});

it('should be iterable with for-of', () => {
queue.push('low', 5);
queue.push('high', 1);
queue.push('mid', 3);

const collected: string[] = [];
for (const value of queue) {
collected.push(value);
}
expect(new Set(collected)).to.deep.equal(new Set(['low', 'high', 'mid']));
});
});
12 changes: 12 additions & 0 deletions tests/Queue/Queue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ describe('Queue', () => {

});

it('should be iterable with for-of', () => {
queue.push(1);
queue.push(2);
queue.push(3);

const collected: number[] = [];
for (const value of queue) {
collected.push(value);
}
expect(collected).to.deep.equal([1, 2, 3]);
});

it('size', () => {

queue.push(1);
Expand Down
12 changes: 12 additions & 0 deletions tests/Stack/Stack.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ describe('Stack', () => {

});

it('should be iterable with for-of', () => {
stack.push(1);
stack.push(2);
stack.push(3);

const collected: number[] = [];
for (const value of stack) {
collected.push(value);
}
expect(collected).to.deep.equal([1, 2, 3]);
});

it('size', () => {

stack.push(1);
Expand Down
11 changes: 11 additions & 0 deletions tests/Tree/Tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,15 @@ describe('Tree', () => {
expect(visitedNodes).to.deep.equal([1, 2, 3, 4, 5]);
});
});

it('should be iterable with for-of', () => {
const root = tree.getRoot();
tree.addChild(root, 2);
tree.addChild(root, 3);
const collected: number[] = [];
for (const val of tree) {
collected.push(val);
}
expect(collected).to.deep.equal([1, 2, 3]);
});
});