Hoe associatieve array/hashing in JavaScript te doen

Ik moet wat statistieken opslaan met JavaScript op een manier zoals ik dat in C# zou doen:

Dictionary<string, int> statistics;
statistics["Foo"] = 10;
statistics["Goo"] = statistics["Goo"] + 1;
statistics.Add("Zoo", 1);

Is er een Hashtableof iets als Dictionary<TKey, TValue>in JavaScript?
Hoe kan ik waarden op zo’n manier opslaan?


Antwoord 1, autoriteit 100%

Gebruik JavaScript-objecten als associatieve arrays.

Associatieve array: in eenvoudige woorden gebruiken associatieve arrays strings in plaats van gehele getallen als index.

Maak een object met

var dictionary = {};

JavaScript stelt u in staat eigenschappen aan objecten toe te voegen met behulp van de volgende syntaxis:

Object.yourProperty = value;

Een alternatieve syntaxis voor hetzelfde is:

Object["yourProperty"] = value;

Als je kunt, maak dan ook key-to-value-objecttoewijzingen met de volgende syntaxis:

var point = { x:3, y:2 };
point["x"] // returns 3
point.y // returns 2

Je kunt als volgt door een associatieve array lopen met behulp van de for..in-lusconstructie

for(var key in Object.keys(dict)){
  var value = dict[key];
  /* use key/value for intended purpose */
}

Antwoord 2, autoriteit 74%

var associativeArray = {};
associativeArray["one"] = "First";
associativeArray["two"] = "Second";
associativeArray["three"] = "Third";

Als je uit een objectgeoriënteerde taal komt, lees dan dit artikel.


Antwoord 3, autoriteit 30%

Alle moderne browsers ondersteunen een JavaScript kaartvoorwerp. Er zijn een aantal redenen die het gebruik van een kaart beter maken dan een object:

  • Een object heeft een prototype, dus er zijn standaardsleutels in de kaart.
  • De sleutels van een object zijn strings, waar ze elke waarde voor een kaart kunnen zijn.
  • Je kunt gemakkelijk de grootte van een kaart bepalen, terwijl je de grootte van een object moet bijhouden.

Voorbeeld:

var myMap = new Map();
var keyObj = {},
    keyFunc = function () {},
    keyString = "a string";
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");
myMap.size; // 3
myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

Als u wilt dat sleutels waarnaar niet wordt verwezen vanuit andere objecten, worden verzameld, kunt u overwegen een WeakMapin plaats van een kaart.


Antwoord 4, autoriteit 23%

Tenzij je een specifieke reden hebt om dat niet te doen, gebruik dan gewoon een normaal object. Er kan naar objecteigenschappen in JavaScript worden verwezen met behulp van hashtable-achtige syntaxis:

var hashtable = {};
hashtable.foo = "bar";
hashtable['bar'] = "foo";

Zowel fooals barelementen kunnen nu worden aangeduid als:

hashtable['foo'];
hashtable['bar'];
// Or
hashtable.foo;
hashtable.bar;

Natuurlijk betekent dit dat uw sleutels strings moeten zijn. Als het geen strings zijn, worden ze intern geconverteerd naar strings, dus het kan nog steeds werken. Uw kilometerstand kan variëren.


Antwoord 5, autoriteit 9%

Aangezien elk object in JavaScript zich gedraagt als – en over het algemeen wordt geïmplementeerd als – een hashtabel, ga ik daar gewoon mee akkoord…

var hashSweetHashTable = {};

Antwoord 6, autoriteit 4%

In C# ziet de code er als volgt uit:

Dictionary<string,int> dictionary = new Dictionary<string,int>();
dictionary.add("sample1", 1);
dictionary.add("sample2", 2);

of

var dictionary = new Dictionary<string, int> {
    {"sample1", 1},
    {"sample2", 2}
};

In JavaScript:

var dictionary = {
    "sample1": 1,
    "sample2": 2
}

A C # Woordenboekobject bevat nuttige methoden, zoals dictionary.ContainsKey()

In JavaScript kunnen we de hasOwnPropertyzoals:

gebruiken

if (dictionary.hasOwnProperty("sample1"))
    console.log("sample1 key found and its value is"+ dictionary["sample1"]);

7, Autoriteit 3%

Als u uw sleutels nodig heeft om een ​​object te zijn in plaats van alleen maar te snijden, kunt u mijn jshashtable gebruiken .


8

function HashTable() {
    this.length = 0;
    this.items = new Array();
    for (var i = 0; i < arguments.length; i += 2) {
        if (typeof (arguments[i + 1]) != 'undefined') {
            this.items[arguments[i]] = arguments[i + 1];
            this.length++;
        }
    }
    this.removeItem = function (in_key) {
        var tmp_previous;
        if (typeof (this.items[in_key]) != 'undefined') {
            this.length--;
            var tmp_previous = this.items[in_key];
            delete this.items[in_key];
        }
        return tmp_previous;
    }
    this.getItem = function (in_key) {
        return this.items[in_key];
    }
    this.setItem = function (in_key, in_value) {
        var tmp_previous;
        if (typeof (in_value) != 'undefined') {
            if (typeof (this.items[in_key]) == 'undefined') {
                this.length++;
            } else {
                tmp_previous = this.items[in_key];
            }
            this.items[in_key] = in_value;
        }
        return tmp_previous;
    }
    this.hasItem = function (in_key) {
        return typeof (this.items[in_key]) != 'undefined';
    }
    this.clear = function () {
        for (var i in this.items) {
            delete this.items[i];
        }
        this.length = 0;
    }
}

9

https://gist.github.com/alexhawkins/f6329420f40e5cafa0a4

var HashTable = function() {
  this._storage = [];
  this._count = 0;
  this._limit = 8;
}
HashTable.prototype.insert = function(key, value) {
  // Create an index for our storage location by passing
  // it through our hashing function
  var index = this.hashFunc(key, this._limit);
  // Retrieve the bucket at this particular index in
  // our storage, if one exists
  //[[ [k,v], [k,v], [k,v] ] , [ [k,v], [k,v] ]  [ [k,v] ] ]
  var bucket = this._storage[index]
  // Does a bucket exist or do we get undefined
  // when trying to retrieve said index?
  if (!bucket) {
    // Create the bucket
    var bucket = [];
    // Insert the bucket into our hashTable
    this._storage[index] = bucket;
  }
  var override = false;
  // Now iterate through our bucket to see if there are any conflicting
  // key value pairs within our bucket. If there are any, override them.
  for (var i = 0; i < bucket.length; i++) {
    var tuple = bucket[i];
    if (tuple[0] === key) {
      // Override value stored at this key
      tuple[1] = value;
      override = true;
    }
  }
  if (!override) {
    // Create a new tuple in our bucket.
    // Note that this could either be the new empty bucket we created above
    // or a bucket with other tupules with keys that are different than
    // the key of the tuple we are inserting. These tupules are in the same
    // bucket because their keys all equate to the same numeric index when
    // passing through our hash function.
    bucket.push([key, value]);
    this._count++
    // Now that we've added our new key/val pair to our storage
    // let's check to see if we need to resize our storage
    if (this._count > this._limit * 0.75) {
      this.resize(this._limit * 2);
    }
  }
  return this;
};
HashTable.prototype.remove = function(key) {
  var index = this.hashFunc(key, this._limit);
  var bucket = this._storage[index];
  if (!bucket) {
    return null;
  }
  // Iterate over the bucket
  for (var i = 0; i < bucket.length; i++) {
    var tuple = bucket[i];
    // Check to see if key is inside bucket
    if (tuple[0] === key) {
      // If it is, get rid of this tuple
      bucket.splice(i, 1);
      this._count--;
      if (this._count < this._limit * 0.25) {
        this._resize(this._limit / 2);
      }
      return tuple[1];
    }
  }
};
HashTable.prototype.retrieve = function(key) {
  var index = this.hashFunc(key, this._limit);
  var bucket = this._storage[index];
  if (!bucket) {
    return null;
  }
  for (var i = 0; i < bucket.length; i++) {
    var tuple = bucket[i];
    if (tuple[0] === key) {
      return tuple[1];
    }
  }
  return null;
};
HashTable.prototype.hashFunc = function(str, max) {
  var hash = 0;
  for (var i = 0; i < str.length; i++) {
    var letter = str[i];
    hash = (hash << 5) + letter.charCodeAt(0);
    hash = (hash & hash) % max;
  }
  return hash;
};
HashTable.prototype.resize = function(newLimit) {
  var oldStorage = this._storage;
  this._limit = newLimit;
  this._count = 0;
  this._storage = [];
  oldStorage.forEach(function(bucket) {
    if (!bucket) {
      return;
    }
    for (var i = 0; i < bucket.length; i++) {
      var tuple = bucket[i];
      this.insert(tuple[0], tuple[1]);
    }
  }.bind(this));
};
HashTable.prototype.retrieveAll = function() {
  console.log(this._storage);
  //console.log(this._limit);
};
/******************************TESTS*******************************/
var hashT = new HashTable();
hashT.insert('Alex Hawkins', '510-599-1930');
//hashT.retrieve();
//[ , , , [ [ 'Alex Hawkins', '510-599-1930' ] ] ]
hashT.insert('Boo Radley', '520-589-1970');
//hashT.retrieve();
//[ , [ [ 'Boo Radley', '520-589-1970' ] ], , [ [ 'Alex Hawkins', '510-599-1930' ] ] ]
hashT.insert('Vance Carter', '120-589-1970').insert('Rick Mires', '520-589-1970').insert('Tom Bradey', '520-589-1970').insert('Biff Tanin', '520-589-1970');
//hashT.retrieveAll();
/*
[ ,
  [ [ 'Boo Radley', '520-589-1970' ],
    [ 'Tom Bradey', '520-589-1970' ] ],
  ,
  [ [ 'Alex Hawkins', '510-599-1930' ],
    [ 'Rick Mires', '520-589-1970' ] ],
  ,
  ,
  [ [ 'Biff Tanin', '520-589-1970' ] ] ]
*/
// Override example (Phone Number Change)
//
hashT.insert('Rick Mires', '650-589-1970').insert('Tom Bradey', '818-589-1970').insert('Biff Tanin', '987-589-1970');
//hashT.retrieveAll();
/*
[ ,
  [ [ 'Boo Radley', '520-589-1970' ],
    [ 'Tom Bradey', '818-589-1970' ] ],
  ,
  [ [ 'Alex Hawkins', '510-599-1930' ],
    [ 'Rick Mires', '650-589-1970' ] ],
  ,
  ,
  [ [ 'Biff Tanin', '987-589-1970' ] ] ]
*/
hashT.remove('Rick Mires');
hashT.remove('Tom Bradey');
//hashT.retrieveAll();
/*
[ ,
  [ [ 'Boo Radley', '520-589-1970' ] ],
  ,
  [ [ 'Alex Hawkins', '510-599-1930' ] ],
  ,
  ,
  [ [ 'Biff Tanin', '987-589-1970' ] ] ]
*/
hashT.insert('Dick Mires', '650-589-1970').insert('Lam James', '818-589-1970').insert('Ricky Ticky Tavi', '987-589-1970');
hashT.retrieveAll();
/* NOTICE HOW THE HASH TABLE HAS NOW DOUBLED IN SIZE UPON REACHING 75% CAPACITY, i.e. 6/8. It is now size 16.
 [,
  ,
  [ [ 'Vance Carter', '120-589-1970' ] ],
  [ [ 'Alex Hawkins', '510-599-1930' ],
    [ 'Dick Mires', '650-589-1970' ],
    [ 'Lam James', '818-589-1970' ] ],
  ,
  ,
  ,
  ,
  ,
  [ [ 'Boo Radley', '520-589-1970' ],
    [ 'Ricky Ticky Tavi', '987-589-1970' ] ],
  ,
  ,
  ,
  ,
  [ [ 'Biff Tanin', '987-589-1970' ] ] ]
*/
console.log(hashT.retrieve('Lam James'));  // 818-589-1970
console.log(hashT.retrieve('Dick Mires')); // 650-589-1970
console.log(hashT.retrieve('Ricky Ticky Tavi')); //987-589-1970
console.log(hashT.retrieve('Alex Hawkins')); // 510-599-1930
console.log(hashT.retrieve('Lebron James')); // null

Antwoord 10

U kunt er een maken door als volgt te gebruiken:

var dictionary = { Name:"Some Programmer", Age:24, Job:"Writing Programs"  };
// Iterate over using keys
for (var key in dictionary) {
  console.log("Key: " + key + " , " + "Value: "+ dictionary[key]);
}
// Access a key using object notation:
console.log("Her name is: " + dictionary.Name)

Other episodes