data-structure-typed 1.47.9 → 1.48.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +49 -48
- package/benchmark/report.html +16 -16
- package/benchmark/report.json +172 -292
- package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +6 -0
- package/dist/cjs/data-structures/binary-tree/avl-tree.js +8 -0
- package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-indexed-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +52 -0
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +106 -28
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +13 -0
- package/dist/cjs/data-structures/binary-tree/bst.js +41 -21
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +16 -0
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +54 -31
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/segment-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multimap.d.ts +28 -0
- package/dist/cjs/data-structures/binary-tree/tree-multimap.js +60 -21
- package/dist/cjs/data-structures/binary-tree/tree-multimap.js.map +1 -1
- package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
- package/dist/cjs/data-structures/hash/hash-map.d.ts +173 -16
- package/dist/cjs/data-structures/hash/hash-map.js +373 -37
- package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
- package/dist/cjs/data-structures/hash/hash-table.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.js.map +1 -1
- package/dist/cjs/data-structures/heap/max-heap.js.map +1 -1
- package/dist/cjs/data-structures/heap/min-heap.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/skip-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/matrix/matrix2d.js.map +1 -1
- package/dist/cjs/data-structures/matrix/navigator.js.map +1 -1
- package/dist/cjs/data-structures/matrix/vector2d.js.map +1 -1
- package/dist/cjs/data-structures/priority-queue/max-priority-queue.js.map +1 -1
- package/dist/cjs/data-structures/priority-queue/min-priority-queue.js.map +1 -1
- package/dist/cjs/data-structures/queue/deque.js.map +1 -1
- package/dist/cjs/data-structures/queue/queue.js.map +1 -1
- package/dist/cjs/data-structures/stack/stack.js.map +1 -1
- package/dist/cjs/data-structures/tree/tree.js.map +1 -1
- package/dist/cjs/data-structures/trie/trie.js.map +1 -1
- package/dist/cjs/types/data-structures/hash/hash-map.d.ts +4 -0
- package/dist/cjs/utils/utils.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +6 -0
- package/dist/mjs/data-structures/binary-tree/avl-tree.js +8 -0
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +52 -0
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +106 -28
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +13 -0
- package/dist/mjs/data-structures/binary-tree/bst.js +41 -21
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +16 -0
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +54 -31
- package/dist/mjs/data-structures/binary-tree/tree-multimap.d.ts +28 -0
- package/dist/mjs/data-structures/binary-tree/tree-multimap.js +60 -21
- package/dist/mjs/data-structures/hash/hash-map.d.ts +173 -16
- package/dist/mjs/data-structures/hash/hash-map.js +369 -35
- package/dist/mjs/types/data-structures/hash/hash-map.d.ts +4 -0
- package/dist/umd/data-structure-typed.js +615 -120
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +9 -0
- package/src/data-structures/binary-tree/binary-tree.ts +109 -24
- package/src/data-structures/binary-tree/bst.ts +38 -19
- package/src/data-structures/binary-tree/rb-tree.ts +55 -31
- package/src/data-structures/binary-tree/tree-multimap.ts +60 -17
- package/src/data-structures/hash/hash-map.ts +400 -40
- package/src/types/data-structures/hash/hash-map.ts +2 -0
- package/test/integration/avl-tree.test.ts +2 -2
- package/test/integration/bst.test.ts +21 -25
- package/test/performance/data-structures/binary-tree/binary-tree.test.ts +17 -12
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +16 -0
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +16 -1
- package/test/unit/data-structures/binary-tree/bst.test.ts +16 -0
- package/test/unit/data-structures/binary-tree/tree-multimap.test.ts +82 -1
- package/test/unit/data-structures/hash/hash-map.test.ts +312 -18
|
@@ -341,4 +341,20 @@ describe('AVLTree iterative methods test', () => {
|
|
|
341
341
|
expect(entries.length).toBe(3);
|
|
342
342
|
expect(entries).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
343
343
|
});
|
|
344
|
+
|
|
345
|
+
test('should clone work well', () => {
|
|
346
|
+
const cloned = avl.clone();
|
|
347
|
+
expect(cloned.root?.left?.key).toBe(1);
|
|
348
|
+
expect(cloned.root?.right?.value).toBe('c');
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test('should keys', () => {
|
|
352
|
+
const keys = avl.keys();
|
|
353
|
+
expect(keys).toEqual([1, 2, 3]);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test('should values', () => {
|
|
357
|
+
const values = avl.values();
|
|
358
|
+
expect(values).toEqual(['a', 'b', 'c']);
|
|
359
|
+
});
|
|
344
360
|
});
|
|
@@ -564,7 +564,6 @@ describe('BinaryTree', () => {
|
|
|
564
564
|
});
|
|
565
565
|
});
|
|
566
566
|
|
|
567
|
-
|
|
568
567
|
describe('BinaryTree iterative methods test', () => {
|
|
569
568
|
let binaryTree: BinaryTree<string>;
|
|
570
569
|
beforeEach(() => {
|
|
@@ -617,4 +616,20 @@ describe('BinaryTree iterative methods test', () => {
|
|
|
617
616
|
expect(entries.length).toBe(3);
|
|
618
617
|
expect(entries).toEqual([[2, 'b'], [1, 'a'], [3, 'c']]);
|
|
619
618
|
});
|
|
619
|
+
|
|
620
|
+
test('should clone work well', () => {
|
|
621
|
+
const cloned = binaryTree.clone();
|
|
622
|
+
expect(cloned.root?.left?.key).toBe(2);
|
|
623
|
+
expect(cloned.root?.right?.value).toBe('c');
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
test('should keys', () => {
|
|
627
|
+
const keys = binaryTree.keys();
|
|
628
|
+
expect(keys).toEqual([2, 1, 3]);
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
test('should values', () => {
|
|
632
|
+
const values = binaryTree.values();
|
|
633
|
+
expect(values).toEqual(['b', 'a', 'c']);
|
|
634
|
+
});
|
|
620
635
|
});
|
|
@@ -900,4 +900,20 @@ describe('BST iterative methods test', () => {
|
|
|
900
900
|
expect(entries.length).toBe(3);
|
|
901
901
|
expect(entries).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
902
902
|
});
|
|
903
|
+
|
|
904
|
+
test('should clone work well', () => {
|
|
905
|
+
const cloned = bst.clone();
|
|
906
|
+
expect(cloned.root?.left).toBe(undefined);
|
|
907
|
+
expect(cloned.root?.right?.value).toBe('b');
|
|
908
|
+
});
|
|
909
|
+
|
|
910
|
+
test('should keys', () => {
|
|
911
|
+
const keys = bst.keys();
|
|
912
|
+
expect(keys).toEqual([1, 2, 3]);
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
test('should values', () => {
|
|
916
|
+
const values = bst.values();
|
|
917
|
+
expect(values).toEqual(['a', 'b', 'c']);
|
|
918
|
+
});
|
|
903
919
|
});
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AVLTreeNode,
|
|
3
|
+
BinaryTreeNode,
|
|
4
|
+
BSTNode,
|
|
5
|
+
CP,
|
|
6
|
+
IterationType,
|
|
7
|
+
TreeMultimap,
|
|
8
|
+
TreeMultimapNode
|
|
9
|
+
} from '../../../../src';
|
|
2
10
|
import { isDebugTest } from '../../../config';
|
|
3
11
|
|
|
4
12
|
const isDebug = isDebugTest;
|
|
@@ -592,3 +600,76 @@ describe('TreeMultimap Performance test', function () {
|
|
|
592
600
|
isDebug && console.log('---lesserOrGreaterTraverse', performance.now() - startL);
|
|
593
601
|
});
|
|
594
602
|
});
|
|
603
|
+
|
|
604
|
+
describe('TreeMultimap iterative methods test', () => {
|
|
605
|
+
let treeMM: TreeMultimap<string>;
|
|
606
|
+
beforeEach(() => {
|
|
607
|
+
treeMM = new TreeMultimap<string>();
|
|
608
|
+
treeMM.add([1, 'a'], 10);
|
|
609
|
+
treeMM.add([2, 'b'], 10);
|
|
610
|
+
treeMM.add([3, 'c'], 1);
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
test('The node obtained by get Node should match the node type', () => {
|
|
614
|
+
const node3 = treeMM.getNode(3);
|
|
615
|
+
expect(node3).toBeInstanceOf(BinaryTreeNode);
|
|
616
|
+
expect(node3).toBeInstanceOf(BSTNode);
|
|
617
|
+
expect(node3).toBeInstanceOf(AVLTreeNode);
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
test('forEach should iterate over all elements', () => {
|
|
621
|
+
const mockCallback = jest.fn();
|
|
622
|
+
treeMM.forEach((entry) => {
|
|
623
|
+
mockCallback(entry);
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
expect(mockCallback.mock.calls.length).toBe(3);
|
|
627
|
+
expect(mockCallback.mock.calls[0][0]).toEqual([1, 'a']);
|
|
628
|
+
expect(mockCallback.mock.calls[1][0]).toEqual([2, 'b']);
|
|
629
|
+
expect(mockCallback.mock.calls[2][0]).toEqual([3, 'c']);
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
test('filter should return a new tree with filtered elements', () => {
|
|
633
|
+
const filteredTree = treeMM.filter(([key]) => key > 1);
|
|
634
|
+
expect(filteredTree.size).toBe(2);
|
|
635
|
+
expect([...filteredTree]).toEqual([[2, 'b'], [3, 'c']]);
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
test('map should return a new tree with modified elements', () => {
|
|
639
|
+
const mappedTree = treeMM.map(([key]) => (key * 2).toString());
|
|
640
|
+
expect(mappedTree.size).toBe(3);
|
|
641
|
+
expect([...mappedTree]).toEqual([[1, '2'], [2, '4'], [3, '6']]);
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
test('reduce should accumulate values', () => {
|
|
645
|
+
const sum = treeMM.reduce((acc, [key]) => acc + key, 0);
|
|
646
|
+
expect(sum).toBe(6);
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
test('[Symbol.iterator] should provide an iterator', () => {
|
|
650
|
+
const entries = [];
|
|
651
|
+
for (const entry of treeMM) {
|
|
652
|
+
entries.push(entry);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
expect(entries.length).toBe(3);
|
|
656
|
+
expect(entries).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
test('should clone work well', () => {
|
|
660
|
+
expect(treeMM.count).toBe(21)
|
|
661
|
+
const cloned = treeMM.clone();
|
|
662
|
+
expect(cloned.root?.left?.key).toBe(1);
|
|
663
|
+
expect(cloned.root?.right?.value).toBe('c');
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
test('should keys', () => {
|
|
667
|
+
const keys = treeMM.keys();
|
|
668
|
+
expect(keys).toEqual([1, 2, 3]);
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
test('should values', () => {
|
|
672
|
+
const values = treeMM.values();
|
|
673
|
+
expect(values).toEqual(['a', 'b', 'c']);
|
|
674
|
+
});
|
|
675
|
+
});
|
|
@@ -1,13 +1,287 @@
|
|
|
1
|
-
import { HashMap } from '../../../../src';
|
|
1
|
+
import { HashMap, LinkedHashMap } from '../../../../src';
|
|
2
2
|
import { getRandomInt, getRandomIntArray } from '../../../utils';
|
|
3
3
|
|
|
4
|
-
describe('HashMap', () => {
|
|
4
|
+
describe('HashMap Test1', () => {
|
|
5
5
|
let hashMap: HashMap<string, number>;
|
|
6
6
|
|
|
7
7
|
beforeEach(() => {
|
|
8
8
|
hashMap = new HashMap<string, number>();
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
+
it('should initialize correctly', () => {
|
|
12
|
+
expect(hashMap.size).toBe(0);
|
|
13
|
+
expect(hashMap.isEmpty()).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should put and get values', () => {
|
|
17
|
+
hashMap.set('one', 1);
|
|
18
|
+
hashMap.set('two', 2);
|
|
19
|
+
hashMap.set('three', 3);
|
|
20
|
+
|
|
21
|
+
expect(hashMap.get('one')).toBe(1);
|
|
22
|
+
expect(hashMap.get('two')).toBe(2);
|
|
23
|
+
expect(hashMap.get('three')).toBe(3);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should handle key collisions', () => {
|
|
27
|
+
// Force a collision by setting two different keys to the same bucket
|
|
28
|
+
hashMap.set('key1', 1);
|
|
29
|
+
hashMap.set('key2', 2);
|
|
30
|
+
|
|
31
|
+
expect(hashMap.get('key1')).toBe(1);
|
|
32
|
+
expect(hashMap.get('key2')).toBe(2);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should delete values', () => {
|
|
36
|
+
hashMap.set('one', 1);
|
|
37
|
+
hashMap.set('two', 2);
|
|
38
|
+
|
|
39
|
+
hashMap.delete('one');
|
|
40
|
+
expect(hashMap.get('one')).toBeUndefined();
|
|
41
|
+
expect(hashMap.size).toBe(1);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should clear the HashMap', () => {
|
|
45
|
+
hashMap.set('one', 1);
|
|
46
|
+
hashMap.set('two', 2);
|
|
47
|
+
|
|
48
|
+
hashMap.clear();
|
|
49
|
+
expect(hashMap.size).toBe(0);
|
|
50
|
+
expect(hashMap.isEmpty()).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should iterate over entries', () => {
|
|
54
|
+
hashMap.set('one', 1);
|
|
55
|
+
hashMap.set('two', 2);
|
|
56
|
+
hashMap.set('three', 3);
|
|
57
|
+
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should resize the table when load factor is exceeded', () => {
|
|
61
|
+
// Set a small initial capacity for testing resizing
|
|
62
|
+
hashMap = new HashMap<string, number>();
|
|
63
|
+
|
|
64
|
+
hashMap.set('one', 1);
|
|
65
|
+
hashMap.set('two', 2);
|
|
66
|
+
hashMap.set('three', 3);
|
|
67
|
+
hashMap.set('four', 4); // This should trigger a resize
|
|
68
|
+
|
|
69
|
+
// expect(hashMap.table.length).toBe(8);
|
|
70
|
+
expect(hashMap.get('one')).toBe(1);
|
|
71
|
+
expect(hashMap.get('two')).toBe(2);
|
|
72
|
+
expect(hashMap.get('three')).toBe(3);
|
|
73
|
+
expect(hashMap.get('four')).toBe(4);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should allow using a custom hash function', () => {
|
|
77
|
+
hashMap = new HashMap<string, number>();
|
|
78
|
+
|
|
79
|
+
hashMap.set('one', 1);
|
|
80
|
+
hashMap.set('two', 2);
|
|
81
|
+
|
|
82
|
+
expect(hashMap.get('one')).toBe(1);
|
|
83
|
+
expect(hashMap.get('two')).toBe(2);
|
|
84
|
+
// Since the custom hash function always returns 0, these keys will collide.
|
|
85
|
+
// Make sure they are stored separately.
|
|
86
|
+
// expect(hashMap.table[0].length).toBe(2);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('HashMap Test2', () => {
|
|
91
|
+
let hashMap: HashMap;
|
|
92
|
+
|
|
93
|
+
beforeEach(() => {
|
|
94
|
+
hashMap = new HashMap();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should create an empty map', () => {
|
|
98
|
+
expect(hashMap.size).toBe(0);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should add a key-value pair', () => {
|
|
102
|
+
hashMap.set('key1', 'value1');
|
|
103
|
+
expect(hashMap.get('key1')).toBe('value1');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should handle object keys correctly', () => {
|
|
107
|
+
const keyObj = { id: 1 };
|
|
108
|
+
hashMap.set(keyObj, 'objectValue');
|
|
109
|
+
expect(hashMap.get(keyObj)).toBe('objectValue');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// it('should handle number keys correctly', () => {
|
|
113
|
+
// hashMap.set(999, { a: '999Value' });
|
|
114
|
+
// hashMap.set('999', {a: '999StrValue'})
|
|
115
|
+
// expect(hashMap.get(999)).toEqual({ a: '999Value' });
|
|
116
|
+
// expect(hashMap.get('999')).toEqual({ a: '999StrValue' });
|
|
117
|
+
// });
|
|
118
|
+
|
|
119
|
+
it('should update the value for an existing key', () => {
|
|
120
|
+
hashMap.set('key1', 'value1');
|
|
121
|
+
hashMap.set('key1', 'newValue');
|
|
122
|
+
expect(hashMap.get('key1')).toBe('newValue');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should return undefined for a non-existent key', () => {
|
|
126
|
+
expect(hashMap.get('nonExistentKey')).toBeUndefined();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should remove a key-value pair', () => {
|
|
130
|
+
hashMap.set('key1', 'value1');
|
|
131
|
+
hashMap.delete('key1');
|
|
132
|
+
expect(hashMap.get('key1')).toBeUndefined();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should clear the map', () => {
|
|
136
|
+
hashMap.set('key1', 'value1');
|
|
137
|
+
expect(hashMap.size).toBe(1);
|
|
138
|
+
|
|
139
|
+
hashMap.clear();
|
|
140
|
+
expect(hashMap.size).toBe(0);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should iterate over values', () => {
|
|
144
|
+
hashMap.set('key1', 'value1');
|
|
145
|
+
hashMap.set('key2', 'value2');
|
|
146
|
+
const values = [];
|
|
147
|
+
for (const value of hashMap) {
|
|
148
|
+
values.push(value);
|
|
149
|
+
}
|
|
150
|
+
expect(values).toEqual([
|
|
151
|
+
['key1', 'value1'],
|
|
152
|
+
['key2', 'value2']
|
|
153
|
+
]);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
function compareHashMaps(hashMap: HashMap<unknown, unknown>, stdMap: Map<unknown, unknown>) {
|
|
157
|
+
expect(hashMap.size).toEqual(stdMap.size);
|
|
158
|
+
stdMap.forEach((value, key) => {
|
|
159
|
+
expect(hashMap.get(key)).toEqual(value);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const stdMap: Map<unknown, unknown> = new Map();
|
|
164
|
+
const arr: number[] = getRandomIntArray(1000, 1, 10000);
|
|
165
|
+
|
|
166
|
+
it('delete test', () => {
|
|
167
|
+
for (const item of arr) {
|
|
168
|
+
stdMap.set(item, item);
|
|
169
|
+
hashMap.set(item, item);
|
|
170
|
+
}
|
|
171
|
+
for (const item of arr) {
|
|
172
|
+
if (Math.random() > 0.6) {
|
|
173
|
+
expect(hashMap.delete(item)).toEqual(stdMap.delete(item));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
compareHashMaps(hashMap, stdMap);
|
|
177
|
+
|
|
178
|
+
for (let i = 0; i < 1000; ++i) {
|
|
179
|
+
const random = getRandomInt(0, 100);
|
|
180
|
+
expect(hashMap.delete(random)).toEqual(stdMap.delete(random));
|
|
181
|
+
}
|
|
182
|
+
compareHashMaps(hashMap, stdMap);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('HashMap for coordinate object keys', () => {
|
|
188
|
+
const hashMap: HashMap<[number, number], number> = new HashMap();
|
|
189
|
+
const codObjs: [number, number][] = [];
|
|
190
|
+
|
|
191
|
+
test('set elements in hash map', () => {
|
|
192
|
+
for (let i = 0; i < 1000; i++) {
|
|
193
|
+
const codObj: [number, number] = [getRandomInt(-10000, 10000), i];
|
|
194
|
+
codObjs.push(codObj);
|
|
195
|
+
hashMap.set(codObj, i);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('get elements in hash map', () => {
|
|
200
|
+
for (let i = 0; i < 1000; i++) {
|
|
201
|
+
const codObj = codObjs[i];
|
|
202
|
+
if (codObj) {
|
|
203
|
+
expect(hashMap.get(codObj)).toBe(i);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test('delete elements in hash map', () => {
|
|
209
|
+
for (let i = 0; i < 1000; i++) {
|
|
210
|
+
if (i === 500) expect(hashMap.size).toBe(500)
|
|
211
|
+
const codObj = codObjs[i];
|
|
212
|
+
if (codObj) hashMap.delete(codObj);
|
|
213
|
+
}
|
|
214
|
+
expect(hashMap.size).toBe(0);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe('HashMap setMany, keys, values', () => {
|
|
220
|
+
const hm: HashMap<number, number> = new HashMap<number, number>();
|
|
221
|
+
|
|
222
|
+
beforeEach(() => {
|
|
223
|
+
hm.clear()
|
|
224
|
+
hm.setMany([[2, 2], [3, 3], [4, 4], [5, 5]])
|
|
225
|
+
hm.setMany([[2, 2], [3, 3], [4, 4], [6, 6]])
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
test('keys', () => {
|
|
229
|
+
expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6])
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test('values', () => {
|
|
233
|
+
expect([...hm.values()]).toEqual([2, 3, 4, 5, 6])
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe('HashMap HOF', () => {
|
|
238
|
+
let hashMap: HashMap;
|
|
239
|
+
|
|
240
|
+
beforeEach(() => {
|
|
241
|
+
hashMap = new HashMap<string, string>();
|
|
242
|
+
hashMap.set('key1', 'value1');
|
|
243
|
+
hashMap.set('key2', 'value2');
|
|
244
|
+
hashMap.set('key3', 'value3');
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test('every() returns true if all elements match the condition', () => {
|
|
248
|
+
expect(hashMap.every((value) => typeof value === 'string')).toBe(true);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test('some() returns true if any element matches the condition', () => {
|
|
252
|
+
expect(hashMap.some((value, key) => key === 'key1')).toBe(true);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test('forEach() should execute a function for each element', () => {
|
|
256
|
+
const mockCallback = jest.fn();
|
|
257
|
+
hashMap.forEach(mockCallback);
|
|
258
|
+
expect(mockCallback.mock.calls.length).toBe(3);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test('map() should transform each element', () => {
|
|
262
|
+
const newHashMap = hashMap.map((value) => value.toUpperCase());
|
|
263
|
+
expect(newHashMap.get('key1')).toBe('VALUE1');
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
test('filter() should remove elements that do not match the condition', () => {
|
|
267
|
+
const filteredHashMap = hashMap.filter((value, key) => key !== 'key1');
|
|
268
|
+
expect(filteredHashMap.has('key1')).toBe(false);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test('reduce() should accumulate values', () => {
|
|
272
|
+
const result = hashMap.reduce((acc, value) => acc + value, '');
|
|
273
|
+
expect(result).toBe('value1value2value3');
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
describe('LinkedHashMap Test1', () => {
|
|
279
|
+
let hashMap: LinkedHashMap<string, number>;
|
|
280
|
+
|
|
281
|
+
beforeEach(() => {
|
|
282
|
+
hashMap = new LinkedHashMap<string, number>();
|
|
283
|
+
});
|
|
284
|
+
|
|
11
285
|
it('should initialize correctly', () => {
|
|
12
286
|
expect(hashMap.size).toBe(0);
|
|
13
287
|
// expect(hashMap.table.length).toBe(16);
|
|
@@ -45,7 +319,7 @@ describe('HashMap', () => {
|
|
|
45
319
|
expect(hashMap.size).toBe(1);
|
|
46
320
|
});
|
|
47
321
|
|
|
48
|
-
it('should clear the
|
|
322
|
+
it('should clear the LinkedHashMap', () => {
|
|
49
323
|
hashMap.set('one', 1);
|
|
50
324
|
hashMap.set('two', 2);
|
|
51
325
|
|
|
@@ -67,7 +341,7 @@ describe('HashMap', () => {
|
|
|
67
341
|
|
|
68
342
|
it('should resize the table when load factor is exceeded', () => {
|
|
69
343
|
// Set a small initial capacity for testing resizing
|
|
70
|
-
hashMap = new
|
|
344
|
+
hashMap = new LinkedHashMap<string, number>();
|
|
71
345
|
|
|
72
346
|
hashMap.set('one', 1);
|
|
73
347
|
hashMap.set('two', 2);
|
|
@@ -82,7 +356,7 @@ describe('HashMap', () => {
|
|
|
82
356
|
});
|
|
83
357
|
|
|
84
358
|
it('should allow using a custom hash function', () => {
|
|
85
|
-
hashMap = new
|
|
359
|
+
hashMap = new LinkedHashMap<string, number>();
|
|
86
360
|
|
|
87
361
|
hashMap.set('one', 1);
|
|
88
362
|
hashMap.set('two', 2);
|
|
@@ -93,13 +367,22 @@ describe('HashMap', () => {
|
|
|
93
367
|
// Make sure they are stored separately.
|
|
94
368
|
// expect(hashMap.table[0].length).toBe(2);
|
|
95
369
|
});
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
// it('should handle number keys correctly', () => {
|
|
373
|
+
// const hm = new LinkedHashMap();
|
|
374
|
+
// hm.set(999, { a: '999Value' });
|
|
375
|
+
// hm.set('999', {a: '999StrValue'})
|
|
376
|
+
// expect(hm.get(999)).toEqual({ a: '999Value' });
|
|
377
|
+
// expect(hm.get('999')).toEqual({ a: '999StrValue1' });
|
|
378
|
+
// });
|
|
96
379
|
});
|
|
97
380
|
|
|
98
|
-
describe('
|
|
99
|
-
let hashMap:
|
|
381
|
+
describe('LinkedHashMap Test2', () => {
|
|
382
|
+
let hashMap: LinkedHashMap;
|
|
100
383
|
|
|
101
384
|
beforeEach(() => {
|
|
102
|
-
hashMap = new
|
|
385
|
+
hashMap = new LinkedHashMap();
|
|
103
386
|
});
|
|
104
387
|
|
|
105
388
|
it('should create an empty map', () => {
|
|
@@ -159,14 +442,7 @@ describe('HashMap', () => {
|
|
|
159
442
|
]);
|
|
160
443
|
});
|
|
161
444
|
|
|
162
|
-
|
|
163
|
-
// hashMap.set('key1', 'value1');
|
|
164
|
-
// hashMap.set('key2', 'value2');
|
|
165
|
-
// hashMap.deleteAt(0);
|
|
166
|
-
// expect(hashMap.get('key1')).toBeUndefined();
|
|
167
|
-
// expect(hashMap.size).toBe(1);
|
|
168
|
-
// });
|
|
169
|
-
function compareHashMaps(hashMap: HashMap<unknown, unknown>, stdMap: Map<unknown, unknown>) {
|
|
445
|
+
function compareHashMaps(hashMap: LinkedHashMap<unknown, unknown>, stdMap: Map<unknown, unknown>) {
|
|
170
446
|
expect(hashMap.size).toEqual(stdMap.size);
|
|
171
447
|
let index = 0;
|
|
172
448
|
stdMap.forEach((value, key) => {
|
|
@@ -230,8 +506,8 @@ describe('HashMap', () => {
|
|
|
230
506
|
});
|
|
231
507
|
});
|
|
232
508
|
|
|
233
|
-
describe('
|
|
234
|
-
const hashMap:
|
|
509
|
+
describe('LinkedHashMap for coordinate object keys', () => {
|
|
510
|
+
const hashMap: LinkedHashMap<[number, number], number> = new LinkedHashMap();
|
|
235
511
|
const codObjs: [number, number][] = [];
|
|
236
512
|
|
|
237
513
|
test('set elements in hash map', () => {
|
|
@@ -261,3 +537,21 @@ describe('HashMap for coordinate object keys', () => {
|
|
|
261
537
|
});
|
|
262
538
|
|
|
263
539
|
});
|
|
540
|
+
|
|
541
|
+
describe('LinkedHashMap setMany, keys, values', () => {
|
|
542
|
+
const hm: LinkedHashMap<number, number> = new LinkedHashMap<number, number>();
|
|
543
|
+
|
|
544
|
+
beforeEach(() => {
|
|
545
|
+
hm.clear()
|
|
546
|
+
hm.setMany([[2, 2], [3, 3], [4, 4], [5, 5]])
|
|
547
|
+
hm.setMany([[2, 2], [3, 3], [4, 4], [6, 6]])
|
|
548
|
+
})
|
|
549
|
+
|
|
550
|
+
test('keys', () => {
|
|
551
|
+
expect(hm.keys()).toEqual([2, 3, 4, 5, 6])
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
test('values', () => {
|
|
555
|
+
expect(hm.values()).toEqual([2, 3, 4, 5, 6])
|
|
556
|
+
});
|
|
557
|
+
});
|