Do the keys of JavaScript associative arrays need to be strings, or can they be any object?
Object keys can only be strings, and even though a developer can use other data types to set an object key, JavaScript automatically converts keys to a string a value.
The key idea is that every Javascript object is an associative array which is the most general sort of array you can invent - sometimes this is called a hash or map structure or a dictionary object. An associative array is simply a set of key value pairs.
An associative array is an array with string keys rather than numeric keys. Associative arrays are dynamic objects that the user redefines as needed. When you assign values to keys in a variable of type Array, the array is transformed into an object, and it loses the attributes and methods of Array.
Arrays in javascript are typically used only with numeric, auto incremented keys, but javascript objects can hold named key value pairs, functions and even other objects as well.
There are no native associative arrays in JavaScript, only objects. Objects have properties. The names of properties are always strings: even the numeric indices of arrays will be converted to strings before the 'array magic' happens.
If you're looking for associative arrays with arbitrary keys, look here.
I've implemented JavaScript HashMap which code can be obtained from http://github.com/lambder/HashMapJS/tree/master
The keys and values can be arbitrary JavaScript objects. There aren't any requirements on objects used as keys or values.
The mechanism is trivial. For every key there is generated a unique id (per HashMap instance). That id is injected to the key object under a high unlikely to collide field name ;)
That id is then used to keying in the underlying baking standard JavaScript association object.
Here is the code:
/*
=====================================================================
@license MIT
@author Lambder
@copyright 2009 Lambder.
@end
=====================================================================
*/
var HashMap = function() {
this.initialize();
}
HashMap.prototype = {
hashkey_prefix: "<#HashMapHashkeyPerfix>",
hashcode_field: "<#HashMapHashkeyPerfix>",
initialize: function() {
this.backing_hash = {};
this.code = 0;
},
/*
Maps value to key, returning the previous association
*/
put: function(key, value) {
var prev;
if (key && value) {
var hashCode = key[this.hashcode_field];
if (hashCode) {
prev = this.backing_hash[hashCode];
} else {
this.code += 1;
hashCode = this.hashkey_prefix + this.code;
key[this.hashcode_field] = hashCode;
}
this.backing_hash[hashCode] = value;
}
return prev;
},
/*
Returns value associated with given key
*/
get: function(key) {
var value;
if (key) {
var hashCode = key[this.hashcode_field];
if (hashCode) {
value = this.backing_hash[hashCode];
}
}
return value;
},
/*
Deletes association by given key.
Returns true if the association existed, false otherwise
*/
del: function(key) {
var success = false;
if (key) {
var hashCode = key[this.hashcode_field];
if (hashCode) {
var prev = this.backing_hash[hashCode];
this.backing_hash[hashCode] = undefined;
if(prev !== undefined)
success = true;
}
}
return success;
}
}
//// Usage
// Creation
var my_map = new HashMap();
// Insertion
var a_key = {};
var a_value = {struct: "structA"};
var b_key = {};
var b_value = {struct: "structB"};
var c_key = {};
var c_value = {struct: "structC"};
my_map.put(a_key, a_value);
my_map.put(b_key, b_value);
var prev_b = my_map.put(b_key, c_value);
// Retrieval
if(my_map.get(a_key) !== a_value){
throw("fail1")
}
if(my_map.get(b_key) !== c_value){
throw("fail2")
}
if(prev_b !== b_value){
throw("fail3")
}
// Deletion
var a_existed = my_map.del(a_key);
var c_existed = my_map.del(c_key);
var a2_existed = my_map.del(a_key);
if(a_existed !== true){
throw("fail4")
}
if(c_existed !== false){
throw("fail5")
}
if(a2_existed !== false){
throw("fail6")
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With