How can I implement an array with an indexer in JavaScript? Is there something like a dictionary in .Net?
You can try buckets, is a javascript data structure library, it allows you to use any type of object in a dictionary.
John Resig (author of jQuery) posted recently on dictionary lookups in javascript.
His solution is to assign the dictionary values as properties of an object. Code pasted verbatim from above article:
// The dictionary lookup object
var dict = {};
// Do a jQuery Ajax request for the text dictionary
$.get( "dict/dict.txt", function( txt ) {
// Get an array of all the words
var words = txt.split( "\n" );
// And add them as properties to the dictionary lookup
// This will allow for fast lookups later
for ( var i = 0; i < words.length; i++ ) {
dict[ words[i] ] = true;
}
// The game would start after the dictionary was loaded
// startGame();
});
// Takes in an array of letters and finds the longest
// possible word at the front of the letters
function findWord( letters ) {
// Clone the array for manipulation
var curLetters = letters.slice( 0 ), word = "";
// Make sure the word is at least 3 letters long
while ( curLetters.length > 2 ) {
// Get a word out of the existing letters
word = curLetters.join("");
// And see if it's in the dictionary
if ( dict[ word ] ) {
// If it is, return that word
return word;
}
// Otherwise remove another letter from the end
curLetters.pop();
}
}
var nDictionary = Object.create(null);
function setDictionary(index, value) {
nDictionary[index] = value;
}
function getDictionary(index) {
return nDictionary[index];
}
setDictionary(81403, "test 1");
setDictionary(81404, "test 2");
setDictionary(81405, "test 3");
setDictionary(81406, "test 4");
setDictionary(81407, "test 5");
alert(getDictionary(81403));
I have this implementation running. The first adding of key value pair makes it kind of key type safe. It works fine and is independent of Map:
Git (is always updated)
function Dictionary() {
this.dictionary = [];
this.validateKey = function(key){
if(typeof key == 'undefined' || key == null){
return false;
}
if(this.dictionary.length){
if (!this.hasOwnProperty(this.dictionary[0], "key")) {
return false;
}
if(typeof this.dictionary[0].key != typeof key){
return false;
}
}
return true;
};
this.hasOwnProperty = function (obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
};
}
Dictionary.prototype = {
Add: function(key, value) {
if(!this.validateKey(key)){
return false;
}
if(!this.ContainsKey(key)){
this.dictionary.push({ key: key, value: value });
return true;
}
return false;
},
Any: function() {
return this.dictionary.length > 0;
},
ContainsKey: function(key) {
if(!this.validateKey(key)){
return false;
}
for (var i = 0; i < this.dictionary.length; i++) {
var keyValuePair = this.dictionary[i];
if (typeof keyValuePair != "undefined" && keyValuePair != null) {
if (this.hasOwnProperty(keyValuePair, "key")) {
if (keyValuePair.key == key) {
return true;
}
}
}
}
return false;
},
ContainsValue: function(value) {
for (var i = 0; i < this.dictionary.length; i++) {
var keyValuePair = this.dictionary[i];
if(typeof keyValuePair != "undefined" && keyValuePair != null){
if (this.hasOwnProperty(keyValuePair, "value")) {
if(value == null && keyValuePair.value == null){
return true;
}
if ((value != null && keyValuePair.value == null) ||
(value == null && keyValuePair.value != null)) {
continue;
}
// compare objects content over json.
if(JSON.stringify(value) === JSON.stringify(keyValuePair.value)){
return true;
}
}
}
}
return false;
},
Count: function() {
return this.dictionary.length;
},
GetValue: function(key){
if(!this.validateKey(key)){
return null;
}
for (var i = 0; i < this.dictionary.length; i++) {
var keyValuePair = this.dictionary[i];
if (typeof keyValuePair != "undefined" && keyValuePair != null) {
if (this.hasOwnProperty(keyValuePair, "key")) {
if (keyValuePair.key == key) {
return keyValuePair.value;
}
}
}
}
return null;
},
Keys: function(){
var keys = [];
for (var i = 0; i < this.dictionary.length; i++) {
var keyValuePair = this.dictionary[i];
if (typeof keyValuePair != "undefined" && keyValuePair != null) {
if (this.hasOwnProperty(keyValuePair, "key")) {
keys.push(keyValuePair.key);
}
}
}
return keys;
},
Remove: function(key){
if(!this.validateKey(key)){
return;
}
for (var i = 0; i < this.dictionary.length; i++) {
var keyValuePair = this.dictionary[i];
if (typeof keyValuePair != "undefined" && keyValuePair != null) {
if (this.hasOwnProperty(keyValuePair, "key")) {
if (keyValuePair.key == key) {
this.dictionary.splice(i, 1);
return;
}
}
}
}
},
Values: function(){
var values = [];
for (var i = 0; i < this.dictionary.length; i++) {
var keyValuePair = this.dictionary[i];
if (typeof keyValuePair != "undefined" && keyValuePair != null) {
if (this.hasOwnProperty(keyValuePair, "value")) {
values.push(keyValuePair.value);
}
}
}
return values;
},
};
This is how you use it:
var dic = new Dictionary();
var success = dic.Add("test", 5);
success = dic.Add("test1", 4);
success = dic.Add("test2", 8);
success = dic.Add(3, 8);
var containsKey = dic.ContainsKey("test2");
containsKey = dic.ContainsKey(3);
var containsValue = dic.ContainsValue(8);
var value = dic.GetValue("test1");
var keys = dic.Keys();
var values = dic.Values();
dic.Remove("test1");
var keys = dic.Keys();
var values = dic.Values();
In JS, {"index":anyValue} is just a dictionary. Your can also refer to definition of JSON (http://www.json.org/)
Use an object as other people write. If you are storing something other than strings as key then just jsonize them. See this blog post for performance considurations of different dictionary implementations in javascript.