data-structure-typed 1.54.3 → 2.0.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/benchmark/report.html +26 -2
- package/benchmark/report.json +292 -42
- package/dist/cjs/data-structures/base/iterable-element-base.d.ts +14 -40
- package/dist/cjs/data-structures/base/iterable-element-base.js +14 -11
- package/dist/cjs/data-structures/base/iterable-element-base.js.map +1 -1
- package/dist/cjs/data-structures/base/linear-base.d.ts +277 -0
- package/dist/cjs/data-structures/base/linear-base.js +553 -0
- package/dist/cjs/data-structures/base/linear-base.js.map +1 -0
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +50 -37
- package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +64 -0
- package/dist/cjs/data-structures/binary-tree/avl-tree.js +64 -0
- package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +62 -0
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +67 -5
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +3 -3
- package/dist/cjs/data-structures/binary-tree/bst.js +14 -14
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/red-black-tree.d.ts +1 -7
- package/dist/cjs/data-structures/binary-tree/red-black-tree.js +1 -7
- package/dist/cjs/data-structures/binary-tree/red-black-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +210 -40
- package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/cjs/data-structures/graph/abstract-graph.js +16 -16
- package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/data-structures/hash/hash-map.d.ts +46 -0
- package/dist/cjs/data-structures/hash/hash-map.js +46 -0
- package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.d.ts +3 -11
- package/dist/cjs/data-structures/heap/heap.js +0 -10
- package/dist/cjs/data-structures/heap/heap.js.map +1 -1
- package/dist/cjs/data-structures/heap/max-heap.d.ts +2 -2
- package/dist/cjs/data-structures/heap/max-heap.js.map +1 -1
- package/dist/cjs/data-structures/heap/min-heap.d.ts +2 -2
- package/dist/cjs/data-structures/heap/min-heap.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +131 -146
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +145 -75
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js +283 -169
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
- package/dist/cjs/data-structures/priority-queue/max-priority-queue.js.map +1 -1
- package/dist/cjs/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
- package/dist/cjs/data-structures/priority-queue/min-priority-queue.js.map +1 -1
- package/dist/cjs/data-structures/priority-queue/priority-queue.d.ts +2 -2
- package/dist/cjs/data-structures/priority-queue/priority-queue.js.map +1 -1
- package/dist/cjs/data-structures/queue/deque.d.ts +130 -91
- package/dist/cjs/data-structures/queue/deque.js +269 -169
- package/dist/cjs/data-structures/queue/deque.js.map +1 -1
- package/dist/cjs/data-structures/queue/queue.d.ts +131 -40
- package/dist/cjs/data-structures/queue/queue.js +181 -50
- package/dist/cjs/data-structures/queue/queue.js.map +1 -1
- package/dist/cjs/data-structures/stack/stack.d.ts +124 -11
- package/dist/cjs/data-structures/stack/stack.js +121 -10
- package/dist/cjs/data-structures/stack/stack.js.map +1 -1
- package/dist/cjs/data-structures/trie/trie.d.ts +4 -3
- package/dist/cjs/data-structures/trie/trie.js +3 -0
- package/dist/cjs/data-structures/trie/trie.js.map +1 -1
- package/dist/cjs/types/data-structures/base/base.d.ts +9 -4
- package/dist/cjs/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
- package/dist/cjs/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
- package/dist/cjs/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
- package/dist/cjs/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
- package/dist/cjs/types/data-structures/queue/deque.d.ts +2 -3
- package/dist/cjs/types/data-structures/queue/queue.d.ts +2 -2
- package/dist/esm/data-structures/base/iterable-element-base.d.ts +14 -40
- package/dist/esm/data-structures/base/iterable-element-base.js +14 -11
- package/dist/esm/data-structures/base/iterable-element-base.js.map +1 -1
- package/dist/esm/data-structures/base/linear-base.d.ts +277 -0
- package/dist/esm/data-structures/base/linear-base.js +549 -0
- package/dist/esm/data-structures/base/linear-base.js.map +1 -0
- package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
- package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js +50 -36
- package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/avl-tree.d.ts +64 -0
- package/dist/esm/data-structures/binary-tree/avl-tree.js +64 -0
- package/dist/esm/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/binary-tree.d.ts +62 -0
- package/dist/esm/data-structures/binary-tree/binary-tree.js +67 -5
- package/dist/esm/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/bst.d.ts +3 -3
- package/dist/esm/data-structures/binary-tree/bst.js +14 -12
- package/dist/esm/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/red-black-tree.d.ts +1 -7
- package/dist/esm/data-structures/binary-tree/red-black-tree.js +1 -7
- package/dist/esm/data-structures/binary-tree/red-black-tree.js.map +1 -1
- package/dist/esm/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
- package/dist/esm/data-structures/binary-tree/tree-multi-map.js +210 -39
- package/dist/esm/data-structures/binary-tree/tree-multi-map.js.map +1 -1
- package/dist/esm/data-structures/graph/abstract-graph.js +16 -16
- package/dist/esm/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/esm/data-structures/hash/hash-map.d.ts +46 -0
- package/dist/esm/data-structures/hash/hash-map.js +46 -0
- package/dist/esm/data-structures/hash/hash-map.js.map +1 -1
- package/dist/esm/data-structures/heap/heap.d.ts +3 -11
- package/dist/esm/data-structures/heap/heap.js +0 -10
- package/dist/esm/data-structures/heap/heap.js.map +1 -1
- package/dist/esm/data-structures/heap/max-heap.d.ts +2 -2
- package/dist/esm/data-structures/heap/max-heap.js.map +1 -1
- package/dist/esm/data-structures/heap/min-heap.d.ts +2 -2
- package/dist/esm/data-structures/heap/min-heap.js.map +1 -1
- package/dist/esm/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
- package/dist/esm/data-structures/linked-list/doubly-linked-list.js +132 -148
- package/dist/esm/data-structures/linked-list/doubly-linked-list.js.map +1 -1
- package/dist/esm/data-structures/linked-list/singly-linked-list.d.ts +145 -75
- package/dist/esm/data-structures/linked-list/singly-linked-list.js +283 -170
- package/dist/esm/data-structures/linked-list/singly-linked-list.js.map +1 -1
- package/dist/esm/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
- package/dist/esm/data-structures/priority-queue/max-priority-queue.js.map +1 -1
- package/dist/esm/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
- package/dist/esm/data-structures/priority-queue/min-priority-queue.js.map +1 -1
- package/dist/esm/data-structures/priority-queue/priority-queue.d.ts +2 -2
- package/dist/esm/data-structures/priority-queue/priority-queue.js.map +1 -1
- package/dist/esm/data-structures/queue/deque.d.ts +130 -91
- package/dist/esm/data-structures/queue/deque.js +269 -169
- package/dist/esm/data-structures/queue/deque.js.map +1 -1
- package/dist/esm/data-structures/queue/queue.d.ts +131 -40
- package/dist/esm/data-structures/queue/queue.js +182 -51
- package/dist/esm/data-structures/queue/queue.js.map +1 -1
- package/dist/esm/data-structures/stack/stack.d.ts +124 -11
- package/dist/esm/data-structures/stack/stack.js +121 -10
- package/dist/esm/data-structures/stack/stack.js.map +1 -1
- package/dist/esm/data-structures/trie/trie.d.ts +4 -3
- package/dist/esm/data-structures/trie/trie.js +3 -0
- package/dist/esm/data-structures/trie/trie.js.map +1 -1
- package/dist/esm/types/data-structures/base/base.d.ts +9 -4
- package/dist/esm/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
- package/dist/esm/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
- package/dist/esm/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
- package/dist/esm/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
- package/dist/esm/types/data-structures/queue/deque.d.ts +2 -3
- package/dist/esm/types/data-structures/queue/queue.d.ts +2 -2
- package/dist/individuals/binary-tree/avl-tree-counter.mjs +4701 -0
- package/dist/individuals/binary-tree/avl-tree-multi-map.mjs +4514 -0
- package/dist/individuals/binary-tree/avl-tree.mjs +4321 -0
- package/dist/individuals/binary-tree/binary-tree.mjs +3097 -0
- package/dist/individuals/binary-tree/bst.mjs +3858 -0
- package/dist/individuals/binary-tree/red-black-tree.mjs +4391 -0
- package/dist/individuals/binary-tree/tree-counter.mjs +4806 -0
- package/dist/individuals/binary-tree/tree-multi-map.mjs +4582 -0
- package/dist/individuals/graph/directed-graph.mjs +2910 -0
- package/dist/individuals/graph/undirected-graph.mjs +2745 -0
- package/dist/individuals/hash/hash-map.mjs +1040 -0
- package/dist/individuals/heap/heap.mjs +909 -0
- package/dist/individuals/heap/max-heap.mjs +671 -0
- package/dist/individuals/heap/min-heap.mjs +659 -0
- package/dist/individuals/linked-list/doubly-linked-list.mjs +1495 -0
- package/dist/individuals/linked-list/singly-linked-list.mjs +1479 -0
- package/dist/individuals/priority-queue/max-priority-queue.mjs +768 -0
- package/dist/individuals/priority-queue/min-priority-queue.mjs +757 -0
- package/dist/individuals/priority-queue/priority-queue.mjs +670 -0
- package/dist/individuals/queue/deque.mjs +1262 -0
- package/dist/individuals/queue/queue.mjs +1865 -0
- package/dist/individuals/stack/stack.mjs +415 -0
- package/dist/individuals/trie/trie.mjs +687 -0
- package/dist/umd/data-structure-typed.js +1260 -649
- package/dist/umd/data-structure-typed.min.js +3 -3
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +7 -7
- package/src/data-structures/base/iterable-element-base.ts +29 -20
- package/src/data-structures/base/linear-base.ts +649 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +51 -36
- package/src/data-structures/binary-tree/avl-tree.ts +64 -0
- package/src/data-structures/binary-tree/binary-tree.ts +5 -5
- package/src/data-structures/binary-tree/bst.ts +9 -9
- package/src/data-structures/binary-tree/tree-multi-map.ts +214 -40
- package/src/data-structures/graph/abstract-graph.ts +16 -16
- package/src/data-structures/hash/hash-map.ts +46 -0
- package/src/data-structures/heap/heap.ts +3 -14
- package/src/data-structures/heap/max-heap.ts +2 -2
- package/src/data-structures/heap/min-heap.ts +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
- package/src/data-structures/linked-list/singly-linked-list.ts +307 -185
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/priority-queue.ts +2 -2
- package/src/data-structures/queue/deque.ts +286 -183
- package/src/data-structures/queue/queue.ts +196 -63
- package/src/data-structures/stack/stack.ts +124 -18
- package/src/data-structures/trie/trie.ts +7 -3
- package/src/types/data-structures/base/base.ts +17 -8
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
- package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
- package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
- package/src/types/data-structures/queue/deque.ts +2 -3
- package/src/types/data-structures/queue/queue.ts +2 -2
- package/test/integration/all-in-one.test.ts +1 -1
- package/test/integration/avl-tree.test.ts +1 -1
- package/test/integration/bst.test.ts +2 -2
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +168 -0
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +15 -14
- package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +165 -7
- package/test/unit/data-structures/graph/directed-graph.test.ts +37 -37
- package/test/unit/data-structures/graph/undirected-graph.test.ts +2 -2
- package/test/unit/data-structures/hash/hash-map.test.ts +135 -0
- package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +135 -27
- package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +183 -12
- package/test/unit/data-structures/queue/deque.test.ts +241 -60
- package/test/unit/data-structures/queue/queue.test.ts +332 -19
- package/test/unit/data-structures/stack/stack.test.ts +165 -0
- package/test/unit/unrestricted-interconversion.test.ts +1 -1
|
@@ -842,3 +842,138 @@ describe('LinkedHashMap', () => {
|
|
|
842
842
|
});
|
|
843
843
|
});
|
|
844
844
|
});
|
|
845
|
+
|
|
846
|
+
describe('classic uses', () => {
|
|
847
|
+
it('@example should maintain insertion order', () => {
|
|
848
|
+
const linkedHashMap = new LinkedHashMap<number, string>();
|
|
849
|
+
linkedHashMap.set(1, 'A');
|
|
850
|
+
linkedHashMap.set(2, 'B');
|
|
851
|
+
linkedHashMap.set(3, 'C');
|
|
852
|
+
|
|
853
|
+
const result = Array.from(linkedHashMap);
|
|
854
|
+
expect(result).toEqual([
|
|
855
|
+
[1, 'A'],
|
|
856
|
+
[2, 'B'],
|
|
857
|
+
[3, 'C']
|
|
858
|
+
]);
|
|
859
|
+
});
|
|
860
|
+
|
|
861
|
+
it('should allow reverse iteration', () => {
|
|
862
|
+
const linkedHashMap = new LinkedHashMap<number, string>();
|
|
863
|
+
linkedHashMap.set(1, 'A');
|
|
864
|
+
linkedHashMap.set(2, 'B');
|
|
865
|
+
linkedHashMap.set(3, 'C');
|
|
866
|
+
|
|
867
|
+
const result = Array.from(linkedHashMap.reverseBegin());
|
|
868
|
+
expect(result).toEqual([
|
|
869
|
+
[3, 'C'],
|
|
870
|
+
[2, 'B'],
|
|
871
|
+
[1, 'A']
|
|
872
|
+
]);
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
it('should allow fast deletion at an index', () => {
|
|
876
|
+
const linkedHashMap = new LinkedHashMap<number, string>();
|
|
877
|
+
linkedHashMap.set(1, 'A');
|
|
878
|
+
linkedHashMap.set(2, 'B');
|
|
879
|
+
linkedHashMap.set(3, 'C');
|
|
880
|
+
|
|
881
|
+
linkedHashMap.deleteAt(1);
|
|
882
|
+
|
|
883
|
+
const result = Array.from(linkedHashMap);
|
|
884
|
+
expect(result).toEqual([
|
|
885
|
+
[1, 'A'],
|
|
886
|
+
[3, 'C']
|
|
887
|
+
]);
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
it('should filter entries correctly', () => {
|
|
891
|
+
const linkedHashMap = new LinkedHashMap<number, string>();
|
|
892
|
+
linkedHashMap.set(1, 'A');
|
|
893
|
+
linkedHashMap.set(2, 'B');
|
|
894
|
+
linkedHashMap.set(3, 'C');
|
|
895
|
+
|
|
896
|
+
const filteredMap = linkedHashMap.filter((key, value) => value !== 'B');
|
|
897
|
+
|
|
898
|
+
const result = Array.from(filteredMap);
|
|
899
|
+
expect(result).toEqual([
|
|
900
|
+
[1, 'A'],
|
|
901
|
+
[3, 'C']
|
|
902
|
+
]);
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
it('should map entries to a new LinkedHashMap', () => {
|
|
906
|
+
const linkedHashMap = new LinkedHashMap<number, string>();
|
|
907
|
+
linkedHashMap.set(1, 'A');
|
|
908
|
+
linkedHashMap.set(2, 'B');
|
|
909
|
+
|
|
910
|
+
const mappedMap = linkedHashMap.map((key, value) => [value, key]);
|
|
911
|
+
|
|
912
|
+
const result = Array.from(mappedMap);
|
|
913
|
+
expect(result).toEqual([
|
|
914
|
+
['A', 1],
|
|
915
|
+
['B', 2]
|
|
916
|
+
]);
|
|
917
|
+
});
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
describe('classic uses', () => {
|
|
921
|
+
it('@example fast lookup of values by key', () => {
|
|
922
|
+
const hashMap = new HashMap<number, string>();
|
|
923
|
+
hashMap.set(1, 'A');
|
|
924
|
+
hashMap.set(2, 'B');
|
|
925
|
+
hashMap.set(3, 'C');
|
|
926
|
+
|
|
927
|
+
expect(hashMap.get(1)).toBe('A');
|
|
928
|
+
expect(hashMap.get(2)).toBe('B');
|
|
929
|
+
expect(hashMap.get(3)).toBe('C');
|
|
930
|
+
expect(hashMap.get(99)).toBeUndefined(); // Key not present
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
it('@example remove duplicates when adding multiple entries', () => {
|
|
934
|
+
const hashMap = new HashMap<number, string>();
|
|
935
|
+
hashMap.set(1, 'A');
|
|
936
|
+
hashMap.set(2, 'B');
|
|
937
|
+
hashMap.set(1, 'C'); // Update value for key 1
|
|
938
|
+
|
|
939
|
+
expect(hashMap.size).toBe(2);
|
|
940
|
+
expect(hashMap.get(1)).toBe('C');
|
|
941
|
+
expect(hashMap.get(2)).toBe('B');
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
it('@example count occurrences of keys', () => {
|
|
945
|
+
const data = [1, 2, 1, 3, 2, 1];
|
|
946
|
+
|
|
947
|
+
const countMap = new HashMap<number, number>();
|
|
948
|
+
for (const key of data) {
|
|
949
|
+
countMap.set(key, (countMap.get(key) || 0) + 1);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
expect(countMap.get(1)).toBe(3);
|
|
953
|
+
expect(countMap.get(2)).toBe(2);
|
|
954
|
+
expect(countMap.get(3)).toBe(1);
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
it('should group entries by a key-derived property', () => {
|
|
958
|
+
const entries = [
|
|
959
|
+
{ id: 1, group: 'A' },
|
|
960
|
+
{ id: 2, group: 'B' },
|
|
961
|
+
{ id: 3, group: 'A' },
|
|
962
|
+
{ id: 4, group: 'B' }
|
|
963
|
+
];
|
|
964
|
+
|
|
965
|
+
const groupedMap = new HashMap<string, number[]>();
|
|
966
|
+
|
|
967
|
+
for (const entry of entries) {
|
|
968
|
+
const group = entry.group;
|
|
969
|
+
const id = entry.id;
|
|
970
|
+
if (!groupedMap.has(group)) {
|
|
971
|
+
groupedMap.set(group, []);
|
|
972
|
+
}
|
|
973
|
+
groupedMap.get(group)?.push(id);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
expect(groupedMap.get('A')).toEqual([1, 3]);
|
|
977
|
+
expect(groupedMap.get('B')).toEqual([2, 4]);
|
|
978
|
+
});
|
|
979
|
+
});
|
|
@@ -32,14 +32,14 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
it('should deleteAt', () => {
|
|
35
|
-
expect(list.deleteAt(1)).toBe(
|
|
36
|
-
expect(list.deleteAt(-1)).toBe(
|
|
37
|
-
expect(list.deleteAt(list.
|
|
38
|
-
expect(list.
|
|
39
|
-
expect(list.deleteAt(4)).toBe(
|
|
35
|
+
expect(list.deleteAt(1)).toBe(2);
|
|
36
|
+
expect(list.deleteAt(-1)).toBe(undefined);
|
|
37
|
+
expect(list.deleteAt(list.length)).toBe(undefined);
|
|
38
|
+
expect(list.length).toBe(4);
|
|
39
|
+
expect(list.deleteAt(4)).toBe(undefined);
|
|
40
40
|
expect([...list]).toEqual([1, 3, 4, 5]);
|
|
41
41
|
expect(list.isEmpty()).toBe(false);
|
|
42
|
-
expect(list.deleteAt(3)).toBe(
|
|
42
|
+
expect(list.deleteAt(3)).toBe(5);
|
|
43
43
|
expect([...list]).toEqual([1, 3, 4]);
|
|
44
44
|
});
|
|
45
45
|
|
|
@@ -103,7 +103,7 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
it('should initialize an empty list', () => {
|
|
106
|
-
expect(list.
|
|
106
|
+
expect(list.length).toBe(0);
|
|
107
107
|
expect(list.head).toBe(undefined);
|
|
108
108
|
expect(list.tail).toBe(undefined);
|
|
109
109
|
});
|
|
@@ -119,17 +119,36 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
119
119
|
list.push(1);
|
|
120
120
|
list.push(2);
|
|
121
121
|
list.push(3);
|
|
122
|
-
expect(list.
|
|
122
|
+
expect(list.length).toBe(3);
|
|
123
123
|
expect(list.head!.value).toBe(1);
|
|
124
124
|
expect(list.tail!.value).toBe(3);
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
+
it('push with maxLen', () => {
|
|
128
|
+
const list = new DoublyLinkedList<number>([], { maxLen: 10 });
|
|
129
|
+
for (let i = 0; i < 1000; i++) {
|
|
130
|
+
list.push(i);
|
|
131
|
+
}
|
|
132
|
+
expect(list.maxLen).toBe(10);
|
|
133
|
+
expect(list.length).toBe(10);
|
|
134
|
+
expect(list.first).toBe(990);
|
|
135
|
+
|
|
136
|
+
list.clear();
|
|
137
|
+
for (let i = 0; i < 1000; i++) {
|
|
138
|
+
list.unshift(i);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
expect(list.maxLen).toBe(10);
|
|
142
|
+
expect(list.length).toBe(10);
|
|
143
|
+
expect(list.last).toBe(990);
|
|
144
|
+
});
|
|
145
|
+
|
|
127
146
|
it('should pop elements from the end of the list', () => {
|
|
128
147
|
list.push(1);
|
|
129
148
|
list.push(2);
|
|
130
149
|
const poppedValue = list.pop();
|
|
131
150
|
expect(poppedValue).toBe(2);
|
|
132
|
-
expect(list.
|
|
151
|
+
expect(list.length).toBe(1);
|
|
133
152
|
expect(list.head!.value).toBe(1);
|
|
134
153
|
expect(list.tail!.value).toBe(1);
|
|
135
154
|
list.pop();
|
|
@@ -145,19 +164,19 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
145
164
|
|
|
146
165
|
// Inserting at the beginning
|
|
147
166
|
list.addAt(0, 0);
|
|
148
|
-
expect(list.
|
|
167
|
+
expect(list.length).toBe(4);
|
|
149
168
|
expect(list.at(0)).toBe(0);
|
|
150
169
|
expect(list.at(1)).toBe(1);
|
|
151
170
|
|
|
152
171
|
// Inserting in the middle
|
|
153
172
|
list.addAt(2, 1.5);
|
|
154
|
-
expect(list.
|
|
173
|
+
expect(list.length).toBe(5);
|
|
155
174
|
expect(list.at(2)).toBe(1.5);
|
|
156
175
|
expect(list.at(3)).toBe(2);
|
|
157
176
|
|
|
158
177
|
// Inserting at the end
|
|
159
178
|
list.addAt(5, 4);
|
|
160
|
-
expect(list.
|
|
179
|
+
expect(list.length).toBe(6);
|
|
161
180
|
expect(list.at(5)).toBe(4);
|
|
162
181
|
expect(list.tail!.value).toBe(4);
|
|
163
182
|
expect(list.at(-1)).toBe(undefined);
|
|
@@ -171,18 +190,18 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
171
190
|
|
|
172
191
|
// Deleting from the beginning
|
|
173
192
|
const deletedValue = list.deleteAt(0);
|
|
174
|
-
expect(deletedValue).toBe(
|
|
175
|
-
expect(list.
|
|
193
|
+
expect(deletedValue).toBe(1);
|
|
194
|
+
expect(list.length).toBe(2);
|
|
176
195
|
expect(list.head!.value).toBe(2);
|
|
177
196
|
|
|
178
197
|
// Deleting from the middle
|
|
179
198
|
list.deleteAt(0); // Deleting the second element
|
|
180
|
-
expect(list.
|
|
199
|
+
expect(list.length).toBe(1);
|
|
181
200
|
expect(list.head!.value).toBe(3);
|
|
182
201
|
|
|
183
202
|
// Deleting from the end
|
|
184
203
|
list.deleteAt(0);
|
|
185
|
-
expect(list.
|
|
204
|
+
expect(list.length).toBe(0);
|
|
186
205
|
expect(list.head).toBe(undefined);
|
|
187
206
|
expect(list.tail).toBe(undefined);
|
|
188
207
|
});
|
|
@@ -193,16 +212,16 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
193
212
|
list.push(3);
|
|
194
213
|
|
|
195
214
|
list.delete(2);
|
|
196
|
-
expect(list.
|
|
215
|
+
expect(list.length).toBe(2);
|
|
197
216
|
expect(list.head!.value).toBe(1);
|
|
198
217
|
expect(list.tail!.value).toBe(3);
|
|
199
218
|
|
|
200
219
|
list.delete(1);
|
|
201
|
-
expect(list.
|
|
220
|
+
expect(list.length).toBe(1);
|
|
202
221
|
expect(list.head!.value).toBe(3);
|
|
203
222
|
|
|
204
223
|
list.delete(3);
|
|
205
|
-
expect(list.
|
|
224
|
+
expect(list.length).toBe(0);
|
|
206
225
|
expect(list.head).toBe(undefined);
|
|
207
226
|
expect(list.tail).toBe(undefined);
|
|
208
227
|
});
|
|
@@ -307,7 +326,7 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
307
326
|
|
|
308
327
|
list.clear();
|
|
309
328
|
|
|
310
|
-
expect(list.
|
|
329
|
+
expect(list.length).toBe(0);
|
|
311
330
|
expect(list.head).toBe(undefined);
|
|
312
331
|
expect(list.tail).toBe(undefined);
|
|
313
332
|
});
|
|
@@ -447,6 +466,95 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
447
466
|
});
|
|
448
467
|
});
|
|
449
468
|
|
|
469
|
+
describe('DoublyLinkedList Additional Methods', () => {
|
|
470
|
+
// Slice method implementation and test
|
|
471
|
+
test('slice should return a new list with specified range', () => {
|
|
472
|
+
const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
|
|
473
|
+
const slicedList = list.slice(1, 4);
|
|
474
|
+
|
|
475
|
+
expect(slicedList.toArray()).toEqual([2, 3, 4]);
|
|
476
|
+
expect(list.length).toBe(5); // Original list unchanged
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// Splice method implementation
|
|
480
|
+
test('splice should modify list and return removed elements', () => {
|
|
481
|
+
const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
|
|
482
|
+
const removedList = list.splice(2, 2, 6, 7);
|
|
483
|
+
|
|
484
|
+
expect(list.toArray()).toEqual([1, 2, 6, 7, 5]);
|
|
485
|
+
expect(removedList.toArray()).toEqual([3, 4]);
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
// Concat method test
|
|
489
|
+
test('concat should combine multiple lists', () => {
|
|
490
|
+
const list1 = new DoublyLinkedList([1, 2]);
|
|
491
|
+
const list2 = new DoublyLinkedList([3, 4]);
|
|
492
|
+
const list3 = new DoublyLinkedList([5, 6]);
|
|
493
|
+
|
|
494
|
+
const concatenatedList = list1.concat(list2, list3);
|
|
495
|
+
expect(concatenatedList.toArray()).toEqual([1, 2, 3, 4, 5, 6]);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
// Sort method test
|
|
499
|
+
test('sort should order elements in ascending order', () => {
|
|
500
|
+
const list = new DoublyLinkedList([5, 2, 8, 1, 9]);
|
|
501
|
+
list.sort((a, b) => a - b);
|
|
502
|
+
|
|
503
|
+
expect(list.toArray()).toEqual([1, 2, 5, 8, 9]);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
// Reverse method test
|
|
507
|
+
test('reverse should invert the list order', () => {
|
|
508
|
+
const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
|
|
509
|
+
list.reverse();
|
|
510
|
+
|
|
511
|
+
expect(list.toArray()).toEqual([5, 4, 3, 2, 1]);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
// Join method test
|
|
515
|
+
test('join should convert list to string with separator', () => {
|
|
516
|
+
const list = new DoublyLinkedList(['a', 'b', 'c']);
|
|
517
|
+
|
|
518
|
+
expect(list.join('-')).toBe('a-b-c');
|
|
519
|
+
expect(list.join()).toBe('a,b,c');
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
// IndexOf method test
|
|
523
|
+
test('indexOf should return first occurrence index', () => {
|
|
524
|
+
const list = new DoublyLinkedList([1, 2, 3, 2, 1]);
|
|
525
|
+
|
|
526
|
+
expect(list.indexOf(2)).toBe(1);
|
|
527
|
+
expect(list.indexOf(4)).toBe(-1);
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// LastIndexOf method test
|
|
531
|
+
test('lastIndexOf should return last occurrence index', () => {
|
|
532
|
+
const list = new DoublyLinkedList([1, 2, 3, 2, 1]);
|
|
533
|
+
|
|
534
|
+
expect(list.lastIndexOf(2)).toBe(3);
|
|
535
|
+
expect(list.lastIndexOf(4)).toBe(-1);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// findIndex method test
|
|
539
|
+
test('findIndex should return first occurrence index', () => {
|
|
540
|
+
const list = new DoublyLinkedList([1, 2, 3, 2, 1]);
|
|
541
|
+
expect(list.findIndex(item => item === 2)).toBe(1);
|
|
542
|
+
expect(list.findIndex(item => item === 4)).toBe(-1);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// fill method test
|
|
546
|
+
test('fill should return fill all the list', () => {
|
|
547
|
+
let list = new DoublyLinkedList([1, 2, 3, 2, 1]);
|
|
548
|
+
expect([...list.fill(9)]).toEqual([9, 9, 9, 9, 9]);
|
|
549
|
+
list = new DoublyLinkedList([1, 2, 3, 2, 1]);
|
|
550
|
+
expect([...list.fill(9, 2, 3)]).toEqual([1, 2, 9, 2, 1]);
|
|
551
|
+
list = new DoublyLinkedList([1, 2, 3, 2, 1]);
|
|
552
|
+
expect([...list.fill(9, -3, -2)]).toEqual([1, 2, 9, 2, 1]);
|
|
553
|
+
list = new DoublyLinkedList([1, 2, 3, 2, 1]);
|
|
554
|
+
expect([...list.fill(9, -2, -3)]).toEqual([1, 2, 3, 2, 1]);
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
|
|
450
558
|
describe('iterable methods', () => {
|
|
451
559
|
it('should forEach, some, every, filter, map, reduce of the deque', () => {
|
|
452
560
|
const dl = new DoublyLinkedList<number>();
|
|
@@ -578,7 +686,7 @@ describe('classic use', () => {
|
|
|
578
686
|
const initialNode = this.currentSong;
|
|
579
687
|
|
|
580
688
|
// Loop through the playlist twice
|
|
581
|
-
for (let i = 0; i < this.playlist.
|
|
689
|
+
for (let i = 0; i < this.playlist.length * 2; i++) {
|
|
582
690
|
playedSongs.push(this.currentSong!.value);
|
|
583
691
|
this.currentSong = this.currentSong!.next || this.playlist.head; // Loop back to the start if needed
|
|
584
692
|
}
|
|
@@ -700,7 +808,7 @@ describe('classic use', () => {
|
|
|
700
808
|
}
|
|
701
809
|
|
|
702
810
|
// Check capacity
|
|
703
|
-
if (this.list.
|
|
811
|
+
if (this.list.length >= this.capacity) {
|
|
704
812
|
// Delete the least recently used element (the tail of the linked list)
|
|
705
813
|
const removedNode = this.list.tail;
|
|
706
814
|
if (removedNode) {
|
|
@@ -745,9 +853,9 @@ describe('classic use', () => {
|
|
|
745
853
|
this.map.clear();
|
|
746
854
|
}
|
|
747
855
|
|
|
748
|
-
// Get the current cache
|
|
749
|
-
get
|
|
750
|
-
return this.list.
|
|
856
|
+
// Get the current cache length
|
|
857
|
+
get length(): number {
|
|
858
|
+
return this.list.length;
|
|
751
859
|
}
|
|
752
860
|
|
|
753
861
|
// Check if it is empty
|
|
@@ -806,7 +914,7 @@ describe('classic use', () => {
|
|
|
806
914
|
|
|
807
915
|
expect(cache.delete('a')).toBe(true);
|
|
808
916
|
expect(cache.get('a')).toBeUndefined();
|
|
809
|
-
expect(cache.
|
|
917
|
+
expect(cache.length).toBe(1);
|
|
810
918
|
|
|
811
919
|
// Should support clearing cache
|
|
812
920
|
cache.clear();
|
|
@@ -814,7 +922,7 @@ describe('classic use', () => {
|
|
|
814
922
|
cache.set('b', 2);
|
|
815
923
|
cache.clear();
|
|
816
924
|
|
|
817
|
-
expect(cache.
|
|
925
|
+
expect(cache.length).toBe(0);
|
|
818
926
|
expect(cache.isEmpty).toBe(true);
|
|
819
927
|
});
|
|
820
928
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SinglyLinkedList, SinglyLinkedListNode } from '../../../../src';
|
|
1
|
+
import { SinglyLinkedList, SinglyLinkedListNode, Stack } from '../../../../src';
|
|
2
2
|
|
|
3
3
|
describe('SinglyLinkedListNode', () => {
|
|
4
4
|
it('should SinglyLinkedList', () => {
|
|
@@ -37,6 +37,16 @@ describe('SinglyLinkedList Operation Test', () => {
|
|
|
37
37
|
list.push(2);
|
|
38
38
|
expect(list.toArray()).toEqual([1, 2]);
|
|
39
39
|
});
|
|
40
|
+
|
|
41
|
+
it('push with maxLen', () => {
|
|
42
|
+
const list = new SinglyLinkedList<number>([], { maxLen: 10 });
|
|
43
|
+
for (let i = 0; i < 1000; i++) {
|
|
44
|
+
list.push(i);
|
|
45
|
+
}
|
|
46
|
+
expect(list.maxLen).toBe(10);
|
|
47
|
+
expect(list.length).toBe(10);
|
|
48
|
+
expect(list.first).toBe(990);
|
|
49
|
+
});
|
|
40
50
|
});
|
|
41
51
|
|
|
42
52
|
describe('pop', () => {
|
|
@@ -187,7 +197,7 @@ describe('SinglyLinkedList Operation Test', () => {
|
|
|
187
197
|
list.push(3);
|
|
188
198
|
list.clear();
|
|
189
199
|
expect(list.toArray()).toEqual([]);
|
|
190
|
-
expect(list.
|
|
200
|
+
expect(list.length).toBe(0);
|
|
191
201
|
expect(list.isEmpty()).toBe(true);
|
|
192
202
|
});
|
|
193
203
|
});
|
|
@@ -277,10 +287,10 @@ describe('SinglyLinkedList Operation Test', () => {
|
|
|
277
287
|
|
|
278
288
|
describe('getLength', () => {
|
|
279
289
|
it('should return the correct length of the list', () => {
|
|
280
|
-
expect(list.
|
|
290
|
+
expect(list.length).toBe(0);
|
|
281
291
|
list.push(1);
|
|
282
292
|
list.push(2);
|
|
283
|
-
expect(list.
|
|
293
|
+
expect(list.length).toBe(2);
|
|
284
294
|
});
|
|
285
295
|
});
|
|
286
296
|
|
|
@@ -290,14 +300,14 @@ describe('SinglyLinkedList Operation Test', () => {
|
|
|
290
300
|
list.push(2);
|
|
291
301
|
list.push(3);
|
|
292
302
|
const removed = list.deleteAt(1);
|
|
293
|
-
expect(removed).toBe(
|
|
303
|
+
expect(removed).toBe(2);
|
|
294
304
|
expect(list.toArray()).toEqual([1, 3]);
|
|
295
305
|
});
|
|
296
306
|
|
|
297
307
|
it('should return undefined for an out-of-bounds index', () => {
|
|
298
308
|
list.push(1);
|
|
299
309
|
const removed = list.deleteAt(1);
|
|
300
|
-
expect(removed).toBe(
|
|
310
|
+
expect(removed).toBe(undefined);
|
|
301
311
|
});
|
|
302
312
|
|
|
303
313
|
it('should delete and return the first element', () => {
|
|
@@ -308,7 +318,7 @@ describe('SinglyLinkedList Operation Test', () => {
|
|
|
308
318
|
const removed = list.deleteAt(0);
|
|
309
319
|
expect(list.first).toBe(2);
|
|
310
320
|
expect(list.last).toBe(2);
|
|
311
|
-
expect(removed).toBe(
|
|
321
|
+
expect(removed).toBe(1);
|
|
312
322
|
expect(list.toArray()).toEqual([2]);
|
|
313
323
|
});
|
|
314
324
|
|
|
@@ -316,7 +326,7 @@ describe('SinglyLinkedList Operation Test', () => {
|
|
|
316
326
|
list.push(1);
|
|
317
327
|
list.push(2);
|
|
318
328
|
const removed = list.deleteAt(1);
|
|
319
|
-
expect(removed).toBe(
|
|
329
|
+
expect(removed).toBe(2);
|
|
320
330
|
expect(list.toArray()).toEqual([1]);
|
|
321
331
|
});
|
|
322
332
|
});
|
|
@@ -448,6 +458,95 @@ describe('SinglyLinkedList Operation Test', () => {
|
|
|
448
458
|
});
|
|
449
459
|
});
|
|
450
460
|
|
|
461
|
+
describe('SinglyLinkedList Additional Methods', () => {
|
|
462
|
+
// Slice method implementation and test
|
|
463
|
+
test('slice should return a new list with specified range', () => {
|
|
464
|
+
const list = new SinglyLinkedList([1, 2, 3, 4, 5]);
|
|
465
|
+
const slicedList = list.slice(1, 4);
|
|
466
|
+
|
|
467
|
+
expect(slicedList.toArray()).toEqual([2, 3, 4]);
|
|
468
|
+
expect(list.length).toBe(5); // Original list unchanged
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
// Splice method implementation
|
|
472
|
+
test('splice should modify list and return removed elements', () => {
|
|
473
|
+
const list = new SinglyLinkedList([1, 2, 3, 4, 5]);
|
|
474
|
+
const removedList = list.splice(2, 2, 6, 7);
|
|
475
|
+
|
|
476
|
+
expect(list.toArray()).toEqual([1, 2, 6, 7, 5]);
|
|
477
|
+
expect(removedList.toArray()).toEqual([3, 4]);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
// Concat method test
|
|
481
|
+
test('concat should combine multiple lists', () => {
|
|
482
|
+
const list1 = new SinglyLinkedList([1, 2]);
|
|
483
|
+
const list2 = new SinglyLinkedList([3, 4]);
|
|
484
|
+
const list3 = new SinglyLinkedList([5, 6]);
|
|
485
|
+
|
|
486
|
+
const concatenatedList = list1.concat(list2, list3);
|
|
487
|
+
expect(concatenatedList.toArray()).toEqual([1, 2, 3, 4, 5, 6]);
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
// Sort method test
|
|
491
|
+
test('sort should order elements in ascending order', () => {
|
|
492
|
+
const list = new SinglyLinkedList([5, 2, 8, 1, 9]);
|
|
493
|
+
list.sort((a, b) => a - b);
|
|
494
|
+
|
|
495
|
+
expect(list.toArray()).toEqual([1, 2, 5, 8, 9]);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
// Reverse method test
|
|
499
|
+
test('reverse should invert the list order', () => {
|
|
500
|
+
const list = new SinglyLinkedList([1, 2, 3, 4, 5]);
|
|
501
|
+
list.reverse();
|
|
502
|
+
|
|
503
|
+
expect(list.toArray()).toEqual([5, 4, 3, 2, 1]);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
// Join method test
|
|
507
|
+
test('join should convert list to string with separator', () => {
|
|
508
|
+
const list = new SinglyLinkedList(['a', 'b', 'c']);
|
|
509
|
+
|
|
510
|
+
expect(list.join('-')).toBe('a-b-c');
|
|
511
|
+
expect(list.join()).toBe('a,b,c');
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
// IndexOf method test
|
|
515
|
+
test('indexOf should return first occurrence index', () => {
|
|
516
|
+
const list = new SinglyLinkedList([1, 2, 3, 2, 1]);
|
|
517
|
+
|
|
518
|
+
expect(list.indexOf(2)).toBe(1);
|
|
519
|
+
expect(list.indexOf(4)).toBe(-1);
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
// LastIndexOf method test
|
|
523
|
+
test('lastIndexOf should return last occurrence index', () => {
|
|
524
|
+
const list = new SinglyLinkedList([1, 2, 3, 2, 1]);
|
|
525
|
+
|
|
526
|
+
expect(list.lastIndexOf(2)).toBe(3);
|
|
527
|
+
expect(list.lastIndexOf(4)).toBe(-1);
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// findIndex method test
|
|
531
|
+
test('findIndex should return first occurrence index', () => {
|
|
532
|
+
const list = new SinglyLinkedList([1, 2, 3, 2, 1]);
|
|
533
|
+
expect(list.findIndex(item => item === 2)).toBe(1);
|
|
534
|
+
expect(list.findIndex(item => item === 4)).toBe(-1);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
// fill method test
|
|
538
|
+
test('fill should return fill all the list', () => {
|
|
539
|
+
let list = new SinglyLinkedList([1, 2, 3, 2, 1]);
|
|
540
|
+
expect([...list.fill(9)]).toEqual([9, 9, 9, 9, 9]);
|
|
541
|
+
list = new SinglyLinkedList([1, 2, 3, 2, 1]);
|
|
542
|
+
expect([...list.fill(9, 2, 3)]).toEqual([1, 2, 9, 2, 1]);
|
|
543
|
+
list = new SinglyLinkedList([1, 2, 3, 2, 1]);
|
|
544
|
+
expect([...list.fill(9, -3, -2)]).toEqual([1, 2, 9, 2, 1]);
|
|
545
|
+
list = new SinglyLinkedList([1, 2, 3, 2, 1]);
|
|
546
|
+
expect([...list.fill(9, -2, -3)]).toEqual([1, 2, 3, 2, 1]);
|
|
547
|
+
});
|
|
548
|
+
});
|
|
549
|
+
|
|
451
550
|
describe('SinglyLinkedList', () => {
|
|
452
551
|
let list: SinglyLinkedList<number>;
|
|
453
552
|
|
|
@@ -458,7 +557,7 @@ describe('SinglyLinkedList', () => {
|
|
|
458
557
|
it('should initialize an empty list', () => {
|
|
459
558
|
expect(list.head).toBe(undefined);
|
|
460
559
|
expect(list.tail).toBe(undefined);
|
|
461
|
-
expect(list.
|
|
560
|
+
expect(list.length).toBe(0);
|
|
462
561
|
});
|
|
463
562
|
|
|
464
563
|
it('should push elements to the end of the list', () => {
|
|
@@ -466,7 +565,7 @@ describe('SinglyLinkedList', () => {
|
|
|
466
565
|
list.push(2);
|
|
467
566
|
expect(list.head!.value).toBe(1);
|
|
468
567
|
expect(list.tail!.value).toBe(2);
|
|
469
|
-
expect(list.
|
|
568
|
+
expect(list.length).toBe(2);
|
|
470
569
|
});
|
|
471
570
|
|
|
472
571
|
it('should pop elements from the end of the list', () => {
|
|
@@ -476,7 +575,7 @@ describe('SinglyLinkedList', () => {
|
|
|
476
575
|
expect(popped).toBe(2);
|
|
477
576
|
expect(list.head!.value).toBe(1);
|
|
478
577
|
expect(list.tail!.value).toBe(1);
|
|
479
|
-
expect(list.
|
|
578
|
+
expect(list.length).toBe(1);
|
|
480
579
|
});
|
|
481
580
|
|
|
482
581
|
it('should reverse the list', () => {
|
|
@@ -545,7 +644,79 @@ describe('iterable methods', () => {
|
|
|
545
644
|
expect(sl.some(element => element > 2)).toBe(true);
|
|
546
645
|
|
|
547
646
|
expect([...sl.filter(element => element > 2)]).toEqual([3]);
|
|
548
|
-
|
|
647
|
+
const mappedSl = sl.map(element => element * 2);
|
|
648
|
+
expect([...mappedSl]).toEqual([2, 4, 6]);
|
|
549
649
|
expect(sl.reduce((accumulator, element) => accumulator + element, 0)).toEqual(6);
|
|
550
650
|
});
|
|
551
651
|
});
|
|
652
|
+
|
|
653
|
+
describe('classic uses', () => {
|
|
654
|
+
|
|
655
|
+
it('@example implementation of a basic text editor', () => {
|
|
656
|
+
|
|
657
|
+
class TextEditor {
|
|
658
|
+
private content: SinglyLinkedList<string>;
|
|
659
|
+
private cursorIndex: number;
|
|
660
|
+
private undoStack: Stack<{ operation: string; data?: any }>;
|
|
661
|
+
|
|
662
|
+
constructor() {
|
|
663
|
+
this.content = new SinglyLinkedList<string>();
|
|
664
|
+
this.cursorIndex = 0; // Cursor starts at the beginning
|
|
665
|
+
this.undoStack = new Stack<{ operation: string; data?: any }>(); // Stack to keep track of operations for undo
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
insert(char: string) {
|
|
669
|
+
this.content.addAt(this.cursorIndex, char);
|
|
670
|
+
this.cursorIndex++;
|
|
671
|
+
this.undoStack.push({ operation: 'insert', data: { index: this.cursorIndex - 1 } });
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
delete() {
|
|
675
|
+
if (this.cursorIndex === 0) return; // Nothing to delete
|
|
676
|
+
const deleted = this.content.deleteAt(this.cursorIndex - 1);
|
|
677
|
+
this.cursorIndex--;
|
|
678
|
+
this.undoStack.push({ operation: 'delete', data: { index: this.cursorIndex, char: deleted } });
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
moveCursor(index: number) {
|
|
682
|
+
this.cursorIndex = Math.max(0, Math.min(index, this.content.length));
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
undo() {
|
|
686
|
+
if (this.undoStack.size === 0) return; // No operations to undo
|
|
687
|
+
const lastAction = this.undoStack.pop();
|
|
688
|
+
|
|
689
|
+
if (lastAction!.operation === 'insert') {
|
|
690
|
+
this.content.deleteAt(lastAction!.data.index);
|
|
691
|
+
this.cursorIndex = lastAction!.data.index;
|
|
692
|
+
} else if (lastAction!.operation === 'delete') {
|
|
693
|
+
this.content.addAt(lastAction!.data.index, lastAction!.data.char);
|
|
694
|
+
this.cursorIndex = lastAction!.data.index + 1;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
getText(): string {
|
|
699
|
+
return [...this.content].join('');
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// Example Usage
|
|
704
|
+
const editor = new TextEditor();
|
|
705
|
+
editor.insert('H');
|
|
706
|
+
editor.insert('e');
|
|
707
|
+
editor.insert('l');
|
|
708
|
+
editor.insert('l');
|
|
709
|
+
editor.insert('o');
|
|
710
|
+
expect(editor.getText()).toBe('Hello'); // Output: "Hello"
|
|
711
|
+
|
|
712
|
+
editor.delete();
|
|
713
|
+
expect(editor.getText()).toBe('Hell'); // Output: "Hell"
|
|
714
|
+
|
|
715
|
+
editor.undo();
|
|
716
|
+
expect(editor.getText()).toBe('Hello'); // Output: "Hello"
|
|
717
|
+
|
|
718
|
+
editor.moveCursor(1);
|
|
719
|
+
editor.insert('a');
|
|
720
|
+
expect(editor.getText()).toBe('Haello'); // Output: "Haello"
|
|
721
|
+
});
|
|
722
|
+
});
|