जावास्क्रिप्ट में साहचर्य सरणी / हैशिंग कैसे करें


574

मुझे जावास्क्रिप्ट का उपयोग करके कुछ आँकड़े संग्रहीत करने की आवश्यकता है जैसे मैं इसे C # में करूँगा:

Dictionary<string, int> statistics;

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

क्या जावास्क्रिप्ट में Hashtableऐसा कुछ है Dictionary<TKey, TValue>?
मैं इस तरह से मूल्यों को कैसे स्टोर कर सकता हूं?


1
js शिथिल टाइप का होता है, इसलिए केवल स्ट्रिंग या इंट की घोषणा करने का कोई तरीका नहीं है, आप बस एक var की घोषणा कर सकते हैं और इसे एक स्ट्रिंग या int असाइन कर सकते हैं। : डी
गॉर्डन गुस्ताफसन

आप xDict की जाँच कर सकते हैं। jsfiddle.net/very/MuVwd यह एक शब्दकोश है = = कुछ भी जावास्क्रिप्ट में लिखा है।
रॉबर्ट

यह लेख साहचर्य सरणियों अंडर-हुड जावास्क्रिप्ट में कार्यान्वित किया जाता है के एक उत्कृष्ट व्याख्या है jayconrod.com/posts/52/a-tour-of-v8-object-representation
Shuklaswag

स्वीकृत उत्तर 2009 में लिखा गया था - यह केवल स्ट्रिंग कुंजी का समर्थन करता है । गैर-स्ट्रिंग कुंजियों के लिए, विटाली के उत्तर में, मानचित्र या कमजोर मानचित्र का उपयोग करें
टूलमेकरसेव

जवाबों:


564

साहचर्य सरणियों के रूप में जावास्क्रिप्ट वस्तुओं का उपयोग करें ।

साहचर्य सरणी: सरल शब्दों में साहचर्य सरणियाँ अनुक्रमणिका के रूप में पूर्णांक संख्या के बजाय स्ट्रिंग्स का उपयोग करती हैं।

के साथ एक ऑब्जेक्ट बनाएँ

var dictionary = {};

जावास्क्रिप्ट आपको निम्नलिखित सिंटैक्स का उपयोग करके ऑब्जेक्ट में गुण जोड़ने की अनुमति देता है:

Object.yourProperty = value;

उसी के लिए एक वैकल्पिक वाक्यविन्यास है:

Object["yourProperty"] = value;

यदि आप निम्न सिंटैक्स के साथ ऑब्जेक्ट मैप्स के लिए मूल्य भी बना सकते हैं

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

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

आप निम्न के लिए for..in लूप निर्माण का उपयोग करके एक सहयोगी सरणी के माध्यम से पुनरावृति कर सकते हैं

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

36
ध्यान दें कि लेखक ने "साहचर्य सरणी" को शुरू करने के दृष्टिकोण new Array()को अपदस्थ किया है। लेख में अंततः इसकी कमियों का उल्लेख किया गया है और सुझाव दिया गया है new Object()या {}पसंदीदा विकल्प के रूप में, लेकिन यह अंत के पास है और मुझे डर है कि अधिकांश पाठकों को यह अब तक नहीं मिलेगा।
डैनियल लुबरोव

23
असफल। जावास्क्रिप्ट ऑब्जेक्ट संदर्भ को कुंजियों के रूप में समर्थन नहीं करता है, जबकि फ्लैश / एएस 3 डिक्शनरी जैसी कोई चीज करता है। जावास्क्रिप्ट में var obj1 = {}; var obj2 = {}; var table= {}; table[obj1] = "A"; table[obj2] = "B"; alert(table[obj1]); //displays B, क्योंकि यह कुंजियों के बीच अंतर नहीं कर सकता है obj1 और obj2; वे दोनों स्ट्रिंग में परिवर्तित हो गए हैं और बस "ऑब्जेक्ट" की तरह बन गए हैं। कुल असफलता, और जावास्क्रिप्ट में संदर्भों और चक्रीय-संदर्भों के साथ कठिन या गैर-प्रदर्शनकारी के साथ टाइप-सुरक्षित क्रमांकन बनाता है। यह Flash / AS3 में आसान है।
त्रिनको

खैर, जेएस में एकमात्र तरीका हम समानता की जांच करके या किसी समान विधि को परिभाषित करके इस तरह से मान्य कर सकते हैं : Point.prototype.equals = function(obj) { return (obj instanceof Point) && (obj.x === this.x) && (obj.y === this.y); };
नदीम 20

1
@ लियो कंसोल.लॉग ({A: eo B ’, C:} D’} [foo]) आपको
14

2
@Leo उदाहरण गलत लगता है। for... inएक शब्दकोष के लिए इसकी कुंजियों पर लूप होगा, इसलिए Object.keysलगता है कि यह वहां पर है। Object.keysशब्दकोश की कुंजियों की एक सरणी देता है, और इसके "कुंजियों" for... inपर एक सरणी लूप के लिए, जो एक सरणी के लिए इसके सूचकांक हैं, न कि इसके मूल्य।
JHH

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

यदि आप एक वस्तु-उन्मुख भाषा से आ रहे हैं, तो आपको इस लेख की जांच करनी चाहिए ।


38
आप इसे कम पंक्तियों में भी कर सकते हैं: var AssociativeArray = {"एक": "पहला", "दो": "दूसरा", "तीन": "तीसरा"}; उसके बाद एसोसिएटिव ऐरे ["एक"] "फर्स्ट" और असोकेरेटिव ऐरे ["चार"] रिटर्न देता है।
टोनी विकम

2
क्षमा करें @JuusoOhtonen, मैंने 6 साल पहले पोस्ट लिखा था (यह अविश्वसनीय है कि समय कितनी तेजी से बढ़ता है)। मैंने लिंक अपडेट कर दिया है। कृपया इसकी जाँच करें और यह पूछने में संकोच न करें कि क्या आपको कोई संदेह है
दानी क्रिके

145

सभी आधुनिक ब्राउज़र एक जावास्क्रिप्ट मैप ऑब्जेक्ट का समर्थन करते हैं । ऐसे कुछ कारण हैं जो किसी ऑब्जेक्ट से बेहतर मैप का उपयोग करते हैं:

  • ऑब्जेक्ट में एक प्रोटोटाइप होता है, इसलिए मैप में डिफ़ॉल्ट कुंजियाँ होती हैं।
  • किसी ऑब्जेक्ट की कुंजी स्ट्रिंग्स हैं, जहां वे किसी मैप के लिए कोई भी मूल्य हो सकते हैं।
  • आप एक ऑब्जेक्ट के लिए आकार का ट्रैक रखने के लिए आसानी से एक मानचित्र का आकार प्राप्त कर सकते हैं।

उदाहरण:

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"

यदि आप ऐसी चाबियां चाहते हैं, जिन्हें अन्य वस्तुओं से कचरा एकत्र नहीं किया जाता है, तो मानचित्र के बजाय कमजोर मानचित्र का उपयोग करने पर विचार करें ।


5
उम्मीद है कि कुछ वर्षों में यह उत्तर के लिए सबसे अधिक मतदान होगा।
कैमरन ली

1
@CameronLee निश्चित रूप से यह होगा
Loerc Faure-Lacroix

1
यह Mapमुश्किल से तब उपयोगी होता है जब आपकी कुंजी एक वस्तु होती है, लेकिन इसकी तुलना मूल्य से की जानी चाहिए, संदर्भ से नहीं।
सियुआन रेन

7
इस उत्तर के लिखे जाने के एक साल से अधिक समय बीत जाने के बाद भी यह सच नहीं है कि "सभी आधुनिक ब्राउज़र मैप का समर्थन करते हैं।" केवल डेस्कटॉप पर ही आप कम से कम बुनियादी मानचित्र समर्थन पर भरोसा कर सकते हैं। मोबाइल उपकरणों पर नहीं। उदाहरण के लिए, एंड्रॉइड ब्राउज़र में कोई मैप समर्थन नहीं है। डेस्कटॉप पर भी, कुछ कार्यान्वयन अपूर्ण हैं। उदाहरण के लिए, IE11 अभी भी "के लिए ... की" के माध्यम से गणना करने का समर्थन नहीं करता है, इसलिए यदि आप IE संगतता चाहते हैं तो आपको घृणित का उपयोग करना होगा। इसके अलावा, JSON.stringify () मेरे द्वारा आजमाए गए किसी भी ब्राउज़र में मैप के लिए काम नहीं करता है। इसके अलावा इनिशियल्स आईई या सफारी में काम नहीं करते हैं।
डेव बर्टन

3
उत्कृष्ट ब्राउज़र समर्थन है। फिर से जांचें। किसी भी मामले में, यह पॉलीफिल के लिए काफी आसान है, इसलिए देशी ब्राउज़र समर्थन एक गैर-मुद्दा है।
ब्रैड

132

जब तक आपके पास एक विशिष्ट कारण नहीं है, बस एक सामान्य वस्तु का उपयोग करें। जावास्क्रिप्ट में ऑब्जेक्ट गुण हैशटेबल-शैली सिंटैक्स का उपयोग करके संदर्भित किया जा सकता है:

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

दोनों fooऔर barतत्वों को अब इस प्रकार संदर्भित किया जा सकता है:

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

बेशक इसका मतलब यह है कि आपकी चाबी को तार होना चाहिए। यदि वे तार नहीं हैं तो वे आंतरिक रूप से तार में परिवर्तित हो जाते हैं, इसलिए यह अभी भी काम कर सकता है, वाईएमएमवी।


1
पूर्णांक के रूप में कीज़ के कारण मुझे कोई समस्या नहीं हुई। stackoverflow.com/questions/2380019/…
जोनास एल्फस्ट्रोम

10
जोनास: ध्यान रखें कि जब संपत्ति सेट की जा रही हो तो आपके पूर्णांक स्ट्रिंग्स में बदल जाते हैं: var hash = {}; hash[1] = "foo"; alert(hash["1"]);अलर्ट "फू"।
टिम डाउन

17
यदि आपकी कोई कुंजी " प्रोटो " या " पैरेंट " है तो क्या होगा?
कृपया

5
ध्यान दें कि ऑब्जेक्ट्स को जावास्क्रिप्ट में कुंजियों के रूप में उपयोग नहीं किया जा सकता है । ठीक है, वे कर सकते हैं, लेकिन वे अपने स्ट्रिंग अभ्यावेदन में परिवर्तित हो जाते हैं, इसलिए कोई भी वस्तु ठीक उसी कुंजी के रूप में समाप्त हो जाएगी। नीचे देखें @ TimDown का jshashtable सुझाव।
एरिटिकोको

21
यह उदाहरण भ्रमित करने वाला है क्योंकि आप फू और बार को दो उदाहरणों में कुंजी और मान के रूप में उपयोग कर रहे हैं। यह दिखाने के लिए बहुत स्पष्ट है कि var dict = {}; dict.key1 = "val1"; dict["key2"] = "val2";तानाशाह के की 1 तत्व को समान रूप से dict["key1"]और दोनों द्वारा संदर्भित किया जा सकता है dict.key1
जिम

49

जेएस में हर वस्तु जैसा व्यवहार करती है - और आमतौर पर इसे लागू किया जाता है - हैशटेबल, मैं बस उसी के साथ जाता हूं ...

var hashSweetHashTable = {};

26
डाउनवोट किया गया क्योंकि यह नहीं दिखाता कि वास्तव में "हैशटेबल" में मूल्यों का उपयोग कैसे किया जाता है।
IQAndreas

मुझे 9 साल की देर हो चुकी है (मुझे प्रोग्रामिंग के बारे में ज्यादा कुछ नहीं पता था, फिर इस साइट को वापस जाने दें), लेकिन ... क्या होगा अगर आप मैप पर पॉइंट स्टोर करने की कोशिश कर रहे हैं, और यह देखने की ज़रूरत है कि क्या कुछ पहले से ही है मानचित्र पर एक बिंदु पर? उस मामले में, आप इसके लिए हैशटेबल का उपयोग करना सबसे अच्छा होगा, निर्देशांक (एक वस्तु , एक स्ट्रिंग नहीं ) द्वारा देख रहे हैं।
माइक वॉरेन

@MikeWarren if (hashSweetHashTable.foo)अगर fooसेट है तो ब्लॉक में प्रवेश करना चाहिए ।
कोरा तुगे

21

इसलिए C # में कोड ऐसा दिखता है:

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

या

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

जावास्क्रिप्ट में

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

सी # शब्दकोश वस्तु की तरह उपयोगी तरीकों में शामिल है dictionary.ContainsKey() जावास्क्रिप्ट में हम इस्तेमाल कर सकते हैं hasOwnPropertyजैसे

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

1
मेरे लिए hasOwnProperty
अपवोट के

18

यदि आपको केवल तार के बजाय किसी भी वस्तु की आवश्यकता है, तो आप मेरे jshashtable का उपयोग कर सकते हैं ।


3
मैंने इस तथ्य के आसपास कितने घंटे ठोकर खाई कि वस्तुओं को वास्तव में जेएस-स्टाइल-ऑब्जेक्ट-एज़-एसोसिएटिव-सरणियों के लिए कुंजी के रूप में इस्तेमाल नहीं किया जा सकता है इससे पहले कि मैंने इसे पाया? धन्यवाद, टिम।
एरिटिकोको

1
फ्लैश / AS3 शब्दकोश, अधिकांश अन्य भाषाओं के साथ, कुंजी के रूप में ऑब्जेक्ट संदर्भ का समर्थन करते हैं। जावास्क्रिप्ट ने अभी भी इसे लागू नहीं किया है, लेकिन मुझे लगता है कि यह भविष्य में कुछ प्रकार के मानचित्र वर्ग के रूप में है। इस बीच फिर से पॉलीफिल्स के साथ; मानकों के लिए बहुत कुछ। ओह, प्रतीक्षा करें ... आखिरकार 2015 में, नक्शा प्रतीत हुआ है: stackoverflow.com/a/30088129/88409 , और "आधुनिक" ब्राउज़रों द्वारा समर्थित है, lol: kangax.github.io/compat-table/6/# नक्शा (और वास्तव में व्यापक रूप से समर्थित नहीं)। एएस 3 के पीछे केवल एक दशक।
त्रिनको जू

टिम, शायद आपको मानचित्र () उपलब्ध होने पर उपयोग करने के लिए jshashtable अपडेट करना चाहिए।
डेव बर्टन

1
@DaveBurton: अच्छी योजना। जैसे ही मेरे पास कुछ समय होगा मैं ऐसा करूंगा।
टिम डाउन

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;
    }
}

1
जो लोग इसे वोट कर रहे हैं, उनके लिए क्या आप टिप्पणी कर सकते हैं क्यों? यह उत्तर 2011 में पोस्ट किया गया था और वर्तमान तिथि में नहीं।
बिरयानी

2
मैंने वोट नहीं डाला लेकिन ... आपको ऑब्जेक्ट के रूप में किसी सरणी का उपयोग नहीं करना चाहिए। 100% यकीन नहीं अगर यह आपका इरादा था। री-इंडेक्स को डिलीट नहीं करने वाले सरणियों पर स्लाइस का उपयोग करें; हटाना ठीक है लेकिन अपरिभाषित करने के लिए सेट होगा - स्पष्ट होना बेहतर; उपयोग = एक वस्तु पर अपरिभाषित भी b / c यह तेज (लेकिन अधिक मेमोरी) है। संक्षेप में: हमेशा किसी ऑब्जेक्ट का उपयोग करें: {}सरणी नहीं: []या new Array()यदि आपके पास स्ट्रिंग कुंजी होने का इरादा है अन्यथा js इंजन में समस्या है - यह या तो 1 चर के लिए 2 प्रकार देखेगा जिसका अर्थ है कि कोई अनुकूलन नहीं है या यह सरणी के साथ चलेगा और एहसास होगा इसे ऑब्जेक्ट (संभव पुन: आवंटन) में बदलना होगा।
ग्रीम विकस्टेड

2
एलेक्स हॉकिन्स के उत्तर के साथ, कृपया कुछ स्पष्टीकरण प्रदान करें कि यह जटिल दिखने वाला कोड वास्तव में उपयोगी क्यों है और यहां दिए गए अन्य छोटे उत्तरों की तुलना में बेहतर है।
थॉमस टेंपेलमैन 11

6

मैंने इसे कुछ समस्या को प्राप्त करने के लिए बनाया था, जैसे कि ऑब्जेक्ट की मैपिंग, गणना की क्षमता ( forEach()विधि के साथ ) और समाशोधन।

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;
        }
    });
}


कक्षा का दस्तावेजीकरण Hashtable

तरीके:

  • get(key)
    निर्दिष्ट कुंजी से संबंधित मान लौटाता है।
    पैरामीटर::
    key वह कुंजी जिसमें से मान प्राप्त होता है।

  • put(key, value)
    निर्दिष्ट मान को निर्दिष्ट कुंजी में जोड़ता है।
    पैरामीटर्स::
    key कुंजी जो मूल्य को जोड़ती है।
    value: कुंजी को संबद्ध करने का मूल्य।

  • remove(key)
    इसके मूल्य के साथ निर्दिष्ट कुंजी निकालता है।
    पैरामीटर::
    key हटाने की कुंजी।

  • clear()
    कुंजी और मान दोनों को हटाते हुए, सभी हैशटेबल को साफ़ करता है।

  • indexOfKey(key)
    जोड़ने के क्रम के आधार पर निर्दिष्ट कुंजी का सूचकांक लौटाता है।
    पैरामीटर्स::
    key कुंजी जिनमें से इंडेक्स मिलता है।

  • indexOfValue(value)
    जोड़ने के क्रम के आधार पर, निर्दिष्ट मूल्य का सूचकांक लौटाता है।
    पैरामीटर्स::
    value जिसका मूल्य इंडेक्स प्राप्त करता है।
    नोट:
    यह जानकारी indexOf()किसी सरणी की विधि द्वारा पुनर्प्राप्त की जाती है , इसलिए यह ऑब्जेक्ट की toString()विधि के साथ तुलना करती है।

  • entryAt(index)
    एक वस्तु को दो गुणों के साथ लौटाता है: कुंजी और मूल्य, निर्दिष्ट सूचकांक पर प्रविष्टि का प्रतिनिधित्व करते हैं।
    पैरामीटर::
    index प्राप्त करने के लिए प्रविष्टि का सूचकांक।

  • containsKey(key)
    हैशटेबल में निर्दिष्ट कुंजी है या नहीं।
    पैरामीटर:
    key जाँच करने के लिए महत्वपूर्ण है।

  • containsValue(value)
    हैशटेबल में निर्दिष्ट मान है या नहीं।
    पैरामीटर::
    value जाँच करने का मान।

  • forEach(iterator)
    निर्दिष्ट सभी प्रविष्टियों को Iterates iterator
    पैरामीटर:
    value :: 3 मानकों के साथ एक विधि key, valueऔर index, जहां indexप्रवेश के सूचकांक का प्रतिनिधित्व करता है।

    गुण:

  • length ( केवल-पढ़ें )
    हैशटेबल में प्रविष्टियों की गिनती हो जाती है।

  • keys ( केवल-पढ़ें )
    हैशटेबल में सभी कुंजियों की एक सरणी बन जाती है।

  • values ( केवल-पढ़ें )
    हैशटेबल में सभी मानों की एक सरणी होती है।

  • entries ( केवल-पढ़ें )
    हैशटेबल में सभी प्रविष्टियों की एक सरणी बन जाती है। वे विधि के समान रूप में दर्शाए गए हैं entryAt()


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

3
अच्छा लगता है। अब, कृपया यह भी बताएं कि यह क्यों उपयोगी है और यहां अन्य सभी उत्तरों की तुलना में बेहतर अनुकूल हो सकता है।
थॉमस टेंपेलमैन 11

1

आप निम्न का उपयोग करके एक बना सकते हैं:

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)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.