Jak wykonać asocjacyjną tablicę / mieszanie w JavaScript

574

Muszę przechowywać niektóre statystyki za pomocą JavaScript w sposób, który zrobiłbym w C #:

Dictionary<string, int> statistics;

statistics["Foo"] = 10;
statistics["Goo"] = statistics["Goo"] + 1;
statistics.Add("Zoo", 1);

Czy w JavaScript jest Hashtablecoś takiego Dictionary<TKey, TValue>?
Jak mogę przechowywać wartości w taki sposób?

George2
źródło
1
js jest luźno wpisany, więc nie ma sposobu, aby po prostu zadeklarować ciąg lub int, możesz po prostu zadeklarować var ​​i przypisać mu ciąg lub int. : D
Gordon Gustafson
Możesz wypróbować xDict. jsfiddle.net/very/MuVwd Jest to słownik String => wszystko napisane w JavaScript.
Robert
Ten artykuł zawiera doskonałe wyjaśnienie, w jaki sposób tablice asocjacyjne są implementowane pod maską w jayconrod.com/posts/52/a-tour-of-v8-object-representation
Shuklaswag
Przyjęta odpowiedź została napisana w 2009 roku - obsługuje tylko klucze łańcuchowe . W przypadku kluczy nieciągłych użyj Map lub WeakMap, jak w odpowiedzi Vitalii .
ToolmakerSteve

Odpowiedzi:

564

Użyj obiektów JavaScript jako tablic asocjacyjnych .

Tablica asocjacyjna: w prostych słowach tablice asocjacyjne używają jako indeksu Ciągów zamiast liczb całkowitych.

Utwórz obiekt za pomocą

var dictionary = {};

JavaScript umożliwia dodawanie właściwości do obiektów przy użyciu następującej składni:

Object.yourProperty = value;

Alternatywna składnia tego samego to:

Object["yourProperty"] = value;

Jeśli możesz także utworzyć klucz do wyceny map obiektów za pomocą następującej składni

var point = { x:3, y:2 };

point["x"] // returns 3
point.y // returns 2

Możesz iterować przez tablicę asocjacyjną za pomocą konstrukcji pętli for..in w następujący sposób

for(var key in Object.keys(dict)){
  var value = dict[key];
  /* use key/value for intended purpose */
}
Alek Davis
źródło
36
Zauważ, że podejście autora do inicjowania „tablicy asocjacyjnej” new Array()jest odrzucone. Artykuł w końcu wspomina o swoich wadach i sugeruje new Object()lub {}jako preferowane alternatywy, ale to już koniec i obawiam się, że większość czytelników nie zajdzie tak daleko.
Daniel Lubarov
23
Zawieść. JavaScript nie obsługuje odwołań do obiektów jako kluczy, podczas gdy coś takiego jak Flash / AS3 Dictionary. W JavaScript, var obj1 = {}; var obj2 = {}; var table= {}; table[obj1] = "A"; table[obj2] = "B"; alert(table[obj1]); //displays Bponieważ nie można rozróżnić kluczy obj1 i obj2; oba są konwertowane na ciąg znaków i po prostu stają się czymś w rodzaju „Object”. Całkowity błąd i sprawia, że ​​serializacja bezpieczna dla typu z nienaruszonymi referencjami i cyklicznymi referencjami jest trudna lub nie działa w JavaScript. Jest to łatwe we Flashu / AS3.
Triynko,
Cóż, jedynym sposobem w JS możemy zweryfikować, sprawdzając równość lub definiując metodę równości przez coś takiego: Point.prototype.equals = function(obj) { return (obj instanceof Point) && (obj.x === this.x) && (obj.y === this.y); };
Nadeem
1
@Leo console.log ({A: 'B', C: 'D'} [foo]) powinien dać ci A B.
ychaouche
2
@Leo Przykład wydaje się błędny. for... insłownik Object.keyszapętla się nad jego kluczami, więc wydaje się , że jest tam źle umieszczony. Object.keysZwraca tablicę klawiszy ze słownika, a for... injeszcze przez pętle tablicy powyżej jego „kluczy”, które w tablicy mają swoje wskaźniki, a nie jego wartości.
JHH
434
var associativeArray = {};
associativeArray["one"] = "First";
associativeArray["two"] = "Second";
associativeArray["three"] = "Third";

Jeśli pochodzisz z języka zorientowanego obiektowo, powinieneś sprawdzić ten artykuł .

Dani Cricco
źródło
38
Możesz to również zrobić w mniejszej liczbie wierszy: var AssociativeArray = {"one": "First", "two": "second", "three": "Third"}; Następnie argument AssociativeArray [„one”] zwraca „First”, a assocativeArray [„four”] zwraca wartość null.
Tony Wickham
2
Przepraszam @JuusoOhtonen, napisałem post 6 lat temu (to niesamowite, jak szybko mija czas). Zaktualizowałem link. Sprawdź to i nie wahaj się zapytać, czy masz jakiekolwiek wątpliwości
Dani Cricco,
145

Wszystkie nowoczesne przeglądarki obsługują obiekt javascript Map . Istnieje kilka powodów, dla których korzystanie z mapy jest lepsze niż obiekt:

  • Obiekt ma prototyp, więc na mapie są domyślne klucze.
  • Klucze obiektu to ciągi znaków, w których mogą mieć dowolną wartość dla mapy.
  • Możesz łatwo uzyskać rozmiar mapy, jednocześnie śledząc rozmiar obiektu.

Przykład:

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"

Jeśli chcesz, aby klucze, do których nie ma odniesienia w innych obiektach, były usuwane , należy rozważyć użycie WeakMap zamiast mapy.

Vitalii Fedorenko
źródło
5
Mam nadzieję, że za kilka lat będzie to najczęściej głosowany na odpowiedź.
Cameron Lee
1
@CameronLee na pewno to zrobi
Loïc Faure-Lacroix,
1
Jest Mapto mało przydatne, gdy klucz jest obiektem, ale należy go porównywać według wartości, a nie odwołania.
Siyuan Ren,
7
Ponad rok po napisaniu tej odpowiedzi nadal NIE jest prawdą, że „wszystkie nowoczesne przeglądarki obsługują Mapę”. Tylko na komputerze możesz liczyć na przynajmniej podstawową obsługę map. Nie na urządzeniach mobilnych. Np. Przeglądarka systemu Android w ogóle nie obsługuje Map. Nawet na pulpicie niektóre implementacje są niekompletne. Na przykład IE11 nadal nie obsługuje wyliczania przez „for ... of ...”, więc jeśli chcesz kompatybilności z IE, musisz użyć obrzydliwego .forEach kludge. Ponadto JSON.stringify () nie działa w Mapach w żadnej przeglądarce, której próbowałem. Inicjatory również nie działają w IE ani Safari.
Dave Burton
3
Istnieje doskonała obsługa przeglądarki. Sprawdź ponownie. W każdym razie jest to dość łatwe do wypełniania, więc natywna obsługa przeglądarki nie jest problemem.
Brad
132

Jeśli nie masz konkretnego powodu, aby tego nie robić, po prostu użyj zwykłego obiektu. Do właściwości obiektów w JavaScript można się odwoływać za pomocą składni w stylu hashtable:

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

Zarówno elementy, jak fooi barelementy mogą być teraz określane jako:

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

Oczywiście oznacza to, że twoje klucze muszą być ciągami znaków. Jeśli nie są łańcuchami, są konwertowane wewnętrznie na łańcuchy, więc może nadal działać, YMMV.

roryf
źródło
1
Klucze jako liczby całkowite nie sprawiły mi problemu. stackoverflow.com/questions/2380019/…
Jonas Elfström
10
Jonas: pamiętaj, że podczas ustawiania właściwości twoje liczby całkowite są konwertowane na ciągi znaków: var hash = {}; hash[1] = "foo"; alert(hash["1"]);ostrzega „foo”.
Tim Down
17
Co jeśli jeden z twoich kluczy to „ proto ” lub „ rodzic ”?
PleaseStand
5
Pamiętaj, że obiektów nie można używać jako kluczy w JavaScript. Cóż, mogą, ale są konwertowane na ich reprezentacje Ciągów, więc każdy Obiekt skończy jako dokładnie ten sam klucz. Zobacz sugestię jshashtable @ TimDown poniżej.
ericsoco,
21
Ten przykład jest mylący, ponieważ używasz foo i bar jako klucza i wartości w dwóch przypadkach. Znacznie jaśniej pokazuje, że var dict = {}; dict.key1 = "val1"; dict["key2"] = "val2";element key1 dict może być przywoływany równo przez oba dict["key1"]i dict.key1.
Jim
49

Ponieważ każdy obiekt w JS zachowuje się - i jest generalnie implementowany jako - tablica mieszająca, po prostu idę z tym ...

var hashSweetHashTable = {};
Shog9
źródło
26
Odebrano, ponieważ nie pokazuje, jak faktycznie uzyskać dostęp do wartości w „tablicy hashtable”.
IQAndreas
Spóźniłem się 9 lat (nie wiedziałem wiele o programowaniu, nie mówiąc już o tej stronie), ale ... Co jeśli próbujesz przechowywać punkty na mapie i musisz sprawdzić, czy coś już jest w punkcie na mapie? W takim przypadku najlepiej byłoby użyć do tego HashTable, patrząc na współrzędne ( obiekt , a nie ciąg znaków ).
Mike Warren,
@MikeWarren if (hashSweetHashTable.foo)powinien wpisać if block, jeśli foojest ustawiony.
Koray Tugay
21

więc w języku C # kod wygląda następująco:

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

lub

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

w JavaScript

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

Obiekt C # Słownik zawiera użyteczne metody jak dictionary.ContainsKey() w JavaScript możemy używać hasOwnPropertyjak

if (dictionary.hasOwnProperty("sample1"))
    console.log("sample1 key found and its value is"+ dictionary["sample1"]);
Raj
źródło
1
Głosujcie za mnie, że nie muszę pisać odpowiedzi na temathasOwnProperty
brichins,
18

Jeśli chcesz, aby twoje klucze były jakimiś obiektami, a nie tylko łańcuchami, możesz użyć mojej jshashtable .

Tim Down
źródło
3
Ile godzin spędziłem na omijaniu faktu, że Przedmioty nie mogą być tak naprawdę używane jako klucze dla tablic JS-style-Object-as-Associative-tablic, zanim to znalazłem? Dziękuję Tim.
ericsoco,
1
Słownik Flash / AS3, podobnie jak większość innych języków, obsługuje odwołania do obiektów jako klucze. JavaScript wciąż go nie implementuje, ale myślę, że będzie w przyszłości specyfikacją jako pewnego rodzaju klasa Map. Tymczasem znowu z polypełniaczami; tyle dla standardów. Och, czekaj ... w końcu w 2015 r. Mapa wydaje się przybyć: stackoverflow.com/a/30088129/88409 i jest obsługiwana przez „nowoczesne” przeglądarki, lol: kangax.github.io/compat-table/es6/# Mapa (i nie bardzo powszechnie obsługiwana). Zaledwie dziesięć lat za AS3.
Triynko,
Tim, być może powinieneś zaktualizować jshashtable, aby używać Map (), jeśli jest dostępny.
Dave Burton,
1
@DaveBurton: Dobry plan. Zrobię to, jak tylko będę miał trochę czasu.
Tim Down
6
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;
    }
}
Birey
źródło
1
Czy w przypadku osób, które głosują na to, możesz skomentować dlaczego? Ta odpowiedź została opublikowana w 2011 r., Ale nie w bieżącej dacie.
Birey,
2
Nie oddałem głosu, ale ... nie powinieneś używać tablicy jako obiektu. Nie jestem w 100% pewien, czy to był twój zamiar. Użyj wycinka na tablicach, nie usuwaj, aby ponownie indeksować; usuwanie jest w porządku, ale zostanie ustawione na niezdefiniowane - lepiej być jawnym; use = undefined na obiekcie zbyt b / c jest szybszy (ale więcej pamięci). W skrócie: zawsze używaj obiektu: {}nie tablicy: []lub new Array()jeśli zamierzasz mieć klucze łańcuchowe, w przeciwnym razie silnik js ma problem - albo zobaczy 2 typy dla 1 zmiennej, co oznacza brak optymalizacji, albo będzie działał z tablicą i zrealizuje musi zmienić się w obiekt (możliwe ponowne przydzielenie).
Graeme Wicksted,
2
Podobnie jak w przypadku odpowiedzi Alexa Hawkinsa, proszę podać wyjaśnienie, dlaczego ten dość skomplikowany kod jest tak naprawdę użyteczny i lepszy niż inne krótsze odpowiedzi podane tutaj.
Thomas Tempelmann
6

Stworzyłem to, aby rozwiązać pewien problem, taki jak mapowanie klucza obiektu, możliwość wyliczenia ( forEach()metodą) i kasowanie.

function Hashtable() {
    this._map = new Map();
    this._indexes = new Map();
    this._keys = [];
    this._values = [];
    this.put = function(key, value) {
        var newKey = !this.containsKey(key);
        this._map.set(key, value);
        if (newKey) {
            this._indexes.set(key, this.length);
            this._keys.push(key);
            this._values.push(value);
        }
    };
    this.remove = function(key) {
        if (!this.containsKey(key))
            return;
        this._map.delete(key);
        var index = this._indexes.get(key);
        this._indexes.delete(key);
        this._keys.splice(index, 1);
        this._values.splice(index, 1);
    };
    this.indexOfKey = function(key) {
        return this._indexes.get(key);
    };
    this.indexOfValue = function(value) {
        return this._values.indexOf(value) != -1;
    };
    this.get = function(key) {
        return this._map.get(key);
    };
    this.entryAt = function(index) {
        var item = {};
        Object.defineProperty(item, "key", {
            value: this.keys[index],
            writable: false
        });
        Object.defineProperty(item, "value", {
            value: this.values[index],
            writable: false
        });
        return item;
    };
    this.clear = function() {
        var length = this.length;
        for (var i = 0; i < length; i++) {
            var key = this.keys[i];
            this._map.delete(key);
            this._indexes.delete(key);
        }
        this._keys.splice(0, length);
    };
    this.containsKey = function(key) {
        return this._map.has(key);
    };
    this.containsValue = function(value) {
        return this._values.indexOf(value) != -1;
    };
    this.forEach = function(iterator) {
        for (var i = 0; i < this.length; i++)
            iterator(this.keys[i], this.values[i], i);
    };
    Object.defineProperty(this, "length", {
        get: function() {
            return this._keys.length;
        }
    });
    Object.defineProperty(this, "keys", {
        get: function() {
            return this._keys;
        }
    });
    Object.defineProperty(this, "values", {
        get: function() {
            return this._values;
        }
    });
    Object.defineProperty(this, "entries", {
        get: function() {
            var entries = new Array(this.length);
            for (var i = 0; i < entries.length; i++)
                entries[i] = this.entryAt(i);
            return entries;
        }
    });
}


Dokumentacja klasy Hashtable

Metody:

  • get(key)
    Zwraca wartość powiązaną z określonym kluczem.
    Parametry::
    key Klucz, z którego pobierana jest wartość.

  • put(key, value)
    Kojarzy określoną wartość z określonym kluczem.
    Parametry::
    key Klucz, z którym powiązana jest wartość.
    value: Wartość do skojarzenia z kluczem.

  • remove(key)
    Usuwa określony klucz z jego wartością.
    Parametry::
    key Klucz do usunięcia.

  • clear()
    Czyści wszystkie tablice mieszające, usuwając zarówno klucze, jak i wartości.

  • indexOfKey(key)
    Zwraca indeks określonego klucza na podstawie kolejności dodawania.
    Parametry:: którego
    key klucz otrzymuje indeks.

  • indexOfValue(value)
    Zwraca indeks określonej wartości na podstawie kolejności dodawania.
    Parametry:: których
    value wartość otrzymuje indeks.
    Uwagi:
    Informacje te są pobierane indexOf()metodą tablic, więc porównuje obiekt tylko z toString()metodą.

  • entryAt(index)
    Zwraca obiekt o dwóch właściwościach: kluczu i wartości, reprezentujących wpis o określonym indeksie.
    Parametry::
    index Indeks wpisu do pobrania.

  • containsKey(key)
    Zwraca, czy tablica skrótów zawiera określony klucz.
    Parametry::
    key Klucz do sprawdzenia.

  • containsValue(value)
    Zwraca, czy tablica skrótów zawiera określoną wartość.
    Parametry::
    value wartość do sprawdzenia.

  • forEach(iterator)
    Iteruje wszystkie wpisy w określonym iterator.
    Parametry:
    value : metoda z 3 parametrów: key, valuei index, gdzie indexreprezentuje indeks wpisu.

    Nieruchomości:

  • length ( Tylko do odczytu )
    Pobiera liczbę wpisów w tablicy mieszającej.

  • keys ( Tylko do odczytu )
    Pobiera tablicę wszystkich kluczy w tablicy mieszającej.

  • values ( Tylko do odczytu )
    Pobiera tablicę wszystkich wartości w tablicy mieszającej.

  • entries ( Tylko do odczytu )
    Pobiera tablicę wszystkich wpisów w tablicy mieszającej. Są reprezentowane w tej samej formie metody entryAt().

Davide Cannizzo
źródło
2

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) {
      //overide 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' ] ] ]
*/

//overide 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 HASH TABLE HAS NOW DOUBLED IN SIZE UPON REACHING 75% CAPACITY ie 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
Alex Hawkins
źródło
3
Wygląda dobrze. Teraz wyjaśnij również, DLACZEGO jest to przydatne i może być bardziej odpowiednie niż wszystkie inne odpowiedzi tutaj.
Thomas Tempelmann
1

Możesz utworzyć taki, korzystając z poniższych:

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)

Ali Ezzat Odeh
źródło