define(
//this comment is needed by jsdoc2 [copy of comment for: function Dictionary(...]
/**
* A dictionary (or map) for key-value storage and access.
* @name Dictionary
* @memberOf mmir.tools
* @class
*
* @example
* var Dictionary = new mmir.require('mmirf/dictionary');
* var d = new Dictionary();
*/
function(){
//set to @ignore in order to avoid doc-duplication in jsdoc3
/**
* A dictionary (or map) for key-value storage and access.
* @constructs mmir.tools.Dictionary
* @ignore
*/
function Dictionary() {
/**
* "map" for the dictionary
*
* @private
*
* @memberOf mmir.tools.Dictionary#
*/
var map = {};
/**
* This list contains the "keys" of all current entries in <tt>map</tt>.
*
* @private
*
* @memberOf mmir.tools.Dictionary#
*/
var keyList = [];
/**
* Prefix for keys in internal MAP object, for avoiding overwrite of
* existing Object properties/functions
*
* @constant
* @private
*
* @memberOf mmir.tools.Dictionary#
*/
var KEY_PREFIX = '$$';
/**
* Helper function that creates the actual lookup key.
*
* The "lookup key" is original key with applied key-prefix.
*
* @param {String} key
* the key (without the internal key prefix)
* @returns {String}
* the key prefixed with the internal key prefix
*
* @private
*
* @memberOf mmir.tools.Dictionary#
*/
var lookupKey = function(key) {
return KEY_PREFIX + key;
};
/** @lends Dictionary.prototype */
return {
/**
* Put / add an entry to the dictionary.
*
* @param {String}
* key the lookup key for the value
* @param {any}
* value the value to store
*
* @public
*
* @memberOf mmir.tools.Dictionary.prototype
*/
put : function(key, value) {
var isAlreadyPresent = this.containsKey(key);
var lKey = lookupKey(key);
map[lKey] = value;
if (!isAlreadyPresent) {
keyList.push(lKey);
}
},
/**
* Check if the dictionary contains an entry for a key.
*
* @param {String}
* key the lookup key to check
* @returns {Boolean} <code>true</code> if an entry exists, otherwise
* <code>false</code>
*
* @public
* @memberOf mmir.tools.Dictionary.prototype
*/
containsKey : function(key) {
return typeof map[lookupKey(key)] !== 'undefined';
},
/**
* Check if the dictionary contains an entry with the value.
*
* <p>
* NOTE that this function may execute rather slowly, with O(n).
*
* @param {any}
* value the value to check
* @param {Boolean}
* [useStrict] if <code>true</code> entry-values are
* checked against param <tt>value</tt> with
* <code>===</code>. If <code>false</code> or omitted,
* values are compared with each other using <code>==</code>.
* @returns {Boolean} <code>true</code> if an entry exists, otherwise
* <code>false</code>
*
* @public
* @memberOf mmir.tools.Dictionary.prototype
*/
containsValue : function(value, useStrict) {
for (var i = 0, size = keyList.length; i < size; ++i) {
if (useStrict) {
if (map[keyList[i]] === value) {
return true;
}
} else {
if (map[keyList[i]] == value) {
return true;
}
}
}
return false;
},
/**
* Get the value for a key.
*
* @param {String}
* key the lookup key with was used to store the entry/value.
* @returns {any} the value for the <tt>key</tt>, or
* <code>undefined</code> if the dictionary has no entry for
* the <tt>key</tt>.
*
* @public
* @memberOf mmir.tools.Dictionary.prototype
*/
get : function(key) {
return map[lookupKey(key)];
},
/**
* Remove an entry from the dictionary.
*
* <p>
* NOTE that this may execute rather slowly, with O(n).
*
*
* @param {String}
* key the lookup key for the entry to remove
* @returns {Boolean} <code>true</code> if the entry was removed. If
* there was no entry for the <tt>key</tt> and nothing was
* removed, <code>false</code> is returned.
*
* @public
* @memberOf mmir.tools.Dictionary.prototype
*/
remove : function(key) {
if (this.containsKey(key)) {
var lKey = lookupKey(key);
// remove from map:
map[lKey] = void(0);
// remove from key-list
for (var i = 0, size = keyList.length; i < size; ++i) {
if (keyList[i] == lKey) {
keyList.splice(i, 1);
break;
}
}
return true;
}
return false;
},
/**
* Get a list of the keys for all entries in the dictionary.
*
* <p>
* The returned list has no specific ordering.
*
* <p>
* NOTE that this may execute rather slowly, with O(n).
*
* <p>
* NOTE that the returned list is no "view" for the keys, i.e. changes
* on this list will not be reflected by the dictionary's key-list.
*
* @returns {Array<String>} a list of all keys
* @public
* @memberOf mmir.tools.Dictionary.prototype
*/
getKeys : function() {
var prefixLen = KEY_PREFIX.length;
var size = keyList.length;
var list = new Array(size);
// create copy of keyList with removed key-prefixes:
for (var i = 0; i < size; ++i) {
list[i] = keyList[i].substring(prefixLen);
}
return list;
},
/**
* Get the size of the dictionary.
*
* @returns {Number} the count of entries in the dictionary
* @public
* @memberOf mmir.tools.Dictionary.prototype
*/
size : function() {
return keyList.length;
},
/**
* Remove all entries from the dictionary.
*
* <p>
* NOTE that this may execute rather slowly, with O(n).
*
* @public
* @memberOf mmir.tools.Dictionary.prototype
*/
clear : function() {
// var size = keyList.length;
// for(var i=0; i < size; ++i){
// delete map[keyList[i]];
// }
// keyList.splice(0, size);
map = void(0);
map = {};
keyList.splice(0, keyList.length);
}
};
};
return Dictionary;
});