1
+ /**
2
+ * Counts items in a string, an array, or an iterable in a similar way as in Python.
3
+ *
4
+ * @class
5
+ */
6
+ class CollectionCounter extends Map {
7
+ /**
8
+ * Create a counter object that counts items of arbitrary types in a string, an array, or an iterable
9
+ * in a manner that is similar to Python. Implementation uses the JS map data structure.
10
+ *
11
+ * @param iterable {string|any[]|Generator} An arbitrary iterable collection, be it an
12
+ * array, a string or a generator. Requires the {@link Symbol.iterator} property.
13
+ * @returns {CollectionCounter } The counter that tracks how many items are there.
14
+ */
15
+ constructor ( iterable ) {
16
+ if ( ! new . target ) {
17
+ return new CollectionCounter ( iterable ) ;
18
+ }
19
+ super ( ) ;
20
+ for ( let item of iterable ) {
21
+ super . set ( item , this . get ( item ) + 1 ) ;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Get how many items are there in the collection.
27
+ *
28
+ * @param item The key to get the count of the item.
29
+ * @returns {number } 0 if the item is not present in the original iterable value.
30
+ */
31
+ get ( item ) {
32
+ const quantity = super . get ( item ) ;
33
+ if ( quantity === undefined ) {
34
+ return 0 ;
35
+ } else {
36
+ return quantity ;
37
+ }
38
+ }
39
+
40
+ set ( ) {
41
+ throw new Error ( "This counter is not supposed to be modified!" ) ;
42
+ }
43
+ }
44
+
45
+ const stringCounter = new CollectionCounter ( "zebra duck elephant kitten bat" ) ;
46
+ const arrayCounter = new CollectionCounter ( [
47
+ 1 , 4 , 2 , 5 , 7 , 4 , 2 , 6 , 3 , 1 ,
48
+ 5 , 3 , 6 , 2 , 7 , 9 , 7 , 8 , 6 , 8 ,
49
+ 5 , 3 , 1 , 6 , 4 , 8 , 4 , 4 , 7 , 0
50
+ ] ) ;
51
+ console . log ( stringCounter ) ;
52
+ console . log ( arrayCounter ) ;
0 commit comments