Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do the keys of JavaScript associative arrays need to be strings, or can they be any object?

Do the keys of JavaScript associative arrays need to be strings, or can they be any object?

like image 748
morgancodes Avatar asked Feb 04 '09 19:02

morgancodes


People also ask

Are JavaScript object keys always strings?

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.

Are JavaScript objects associative arrays?

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.

What is key in associative array?

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.

Do JavaScript arrays have keys?

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.


2 Answers

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.

like image 101
Christoph Avatar answered Sep 20 '22 05:09

Christoph


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")
}
like image 37
Lambder Avatar answered Sep 18 '22 05:09

Lambder