1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
/**
* @license
* Copyright The Closure Library Authors.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Datastructure: Hash Map.
*
* This file provides a goog.structs.Map interface based on native Map.
*/
goog.module('goog.ui.Map');
goog.module.declareLegacyNamespace();
/**
* Class for Hash Map datastructure.
* @param {*=} map Map or Object to initialize the map with.
* @constructor
* @template K, V
*/
const UiMap = function(map = undefined) {
/** @private @const {!Map<K, V>} */
this.map_ = new Map();
const argLength = arguments.length;
if (argLength > 1) {
if (argLength % 2) {
throw new Error('Uneven number of arguments');
}
for (let i = 0; i < argLength; i += 2) {
this.set(arguments[i], arguments[i + 1]);
}
} else if (map) {
this.addAll(/** @type {!Object} */ (map));
}
};
/**
* @return {number} The number of key-value pairs in the map.
*/
UiMap.prototype.getCount = function() {
return this.map_.size;
};
/**
* Returns the values of the map.
* @return {!Array<V>} The values in the map.
*/
UiMap.prototype.getValues = function() {
return Array.from(this.map_.values());
};
/**
* Returns the keys of the map.
* @return {!Array<K>} Array of string values.
*/
UiMap.prototype.getKeys = function() {
return Array.from(this.map_.keys());
};
/**
* Whether the map contains the given key.
* @param {K} key The key to check for.
* @return {boolean} Whether the map contains the key.
*/
UiMap.prototype.containsKey = function(key) {
return this.map_.has(key);
};
/**
* Whether the map contains the given value. This is O(n).
* @param {V} val The value to check for.
* @return {boolean} Whether the map contains the value.
*/
UiMap.prototype.containsValue = function(val) {
// NOTE: goog.structs.Map uses == instead of ===.
return this.getValues().some((v) => v == val);
};
/**
* Whether this map is equal to the argument map.
* @param {!UiMap} otherMap The map against which to test equality.
* @param {function(V, V): boolean=} equalityFn Optional equality function
* to test equality of values. If not specified, this will test whether
* the values contained in each map are identical objects.
* @return {boolean} Whether the maps are equal.
*/
UiMap.prototype.equals = function(
otherMap, equalityFn = (a, b) => a === b) {
if (this === otherMap) {
return true;
}
if (this.map_.size != otherMap.getCount()) {
return false;
}
return this.getKeys().every((key) => {
return equalityFn(this.map_.get(key), otherMap.get(key));
});
};
/**
* @return {boolean} Whether the map is empty.
*/
UiMap.prototype.isEmpty = function() {
return this.map_.size == 0;
};
/**
* Removes all key-value pairs from the map.
*/
UiMap.prototype.clear = function() {
this.map_.clear();
};
/**
* Removes a key-value pair based on the key. This is O(logN) amortized due to
* updating the keys array whenever the count becomes half the size of the keys
* in the keys array.
* @param {K} key The key to remove.
* @return {boolean} Whether object was removed.
*/
UiMap.prototype.remove = function(key) {
return this.map_.delete(key);
};
/**
* Returns the value for the given key. If the key is not found and the default
* value is not given this will return `undefined`.
* @param {*} key The key to get the value for.
* @param {DEFAULT=} defaultValue The value to return if no item is found for
* the given key, defaults to undefined.
* @return {V|DEFAULT} The value for the given key.
* @template DEFAULT
*/
UiMap.prototype.get = function(key, defaultValue = undefined) {
if (this.map_.has(key)) {
return this.map_.get(key);
}
return defaultValue;
};
/**
* Adds a key-value pair to the map.
* @param {*} key The key.
* @param {V} value The value to add.
* @return {!THIS} Some subclasses return a value.
* @this {THIS}
* @template THIS
*/
UiMap.prototype.set = function(key, value) {
const self = /** @type {!UiMap} */ (this);
self.map_.set(key, value);
return self;
};
/**
* Adds multiple key-value pairs from another goog.ui.Map or Object.
* @param {!Object<K, V>} map Object containing the data to add.
*/
UiMap.prototype.addAll = function(map) {
if (map instanceof UiMap) {
for (const [key, val] of map.map_) {
this.map_.set(key, val);
}
} else if (!!map) {
for (const [key, val] of Object.entries(map)) {
this.map_.set(key, val);
}
}
};
/**
* Calls the given function on each entry in the map.
* @param {function(this:T, V, K, (!Map|!UiMap<K,V>|null))} callbackFn
* @param {T=} thisArg The value of "this" inside callbackFn.
* @template T
*/
UiMap.prototype.forEach = function(callbackFn, thisArg = this) {
this.map_.forEach((val, key) => callbackFn.call(thisArg, val, key, this));
};
/**
* Clones a map and returns a new map.
* @return {!UiMap} A new map with the same key-value pairs.
*/
UiMap.prototype.clone = function() {
return new UiMap(this);
};
/**
* @return {!Object} Object representation of the map.
*/
UiMap.prototype.toObject = function() {
const obj = {};
for (const [key, val] of this.map_) {
obj[key] = val;
}
return obj;
};
exports = UiMap;
|