سؤال

أنا بحاجة إلى تخزين بعض الإحصاءات باستخدام جافا سكريبت في طريقة مثل كنت تفعل ذلك في C#:

Dictionary<string, int> statistics;

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

هناك Hashtable أو شيء من هذا القبيل Dictionary<TKey, TValue> في جافا سكريبت ؟
كيف يمكنني تخزين القيم في مثل هذه الطريقة ؟

هل كانت مفيدة؟

المحلول

جافا سكريبت الكائنات كما صفائف النقابي .

<اقتباس فقرة>   

والجمعياتي صفيف: في كلمات بسيطة تستخدم صفائف النقابي سلاسل بدلا من أرقام الصحيحة كما مؤشر

.

وإنشاء كائن مع

var dictionary = {};
<اقتباس فقرة>   

وجافا سكريبت يسمح لك بإضافة خصائص الكائنات باستخدام بناء الجملة التالي:

Object.yourProperty = value;

وبناء جملة بديل لنفسه هو:

Object["yourProperty"] = value;

إذا يمكنك أيضا إنشاء مفتاح الخرائط وجوه القيمة مع بناء الجملة التالية

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

point["x"] // returns 3
point.y // returns 2
<اقتباس فقرة>   

ويمكنك تكرار من خلال مجموعة النقابي باستخدام دالة for..in loop بناء على النحو التالي

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

نصائح أخرى

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

إذا كنت قادما من لغة وجوه المنحى يجب عليك التحقق من هذه المقالة .

واذا لم يكن هناك سبب محدد لا، مجرد استخدام كائن طبيعي. ويمكن الرجوع إليها خصائص الكائن في جافا سكريبت باستخدام بناء الجملة على غرار جدول هاش:

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

ويمكن الآن ثم يتم الرجوع إليها كل العناصر foo وbar على النحو التالي:

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

وبطبيعة الحال هذا لا يعني المفاتيح الخاصة بك يجب أن تكون السلاسل. لو لم تكن سلاسل يتم تحويلها داخليا إلى سلاسل، لذلك قد لا تزال تعمل، YMMV.

جميع المتصفحات الحديثة دعم جافا سكريبت خريطة الكائن.هناك اثنين من الأسباب التي تجعل استخدام الخريطة أفضل من وجوه:

  • كائن لديه النموذج ، لذا هناك المفاتيح الافتراضية في الخريطة.
  • مفاتيح كائن هي سلاسل, حيث أنها يمكن أن تكون أي قيمة على الخريطة.
  • يمكنك الحصول على حجم الخريطة بسهولة في حين يجب أن تتبع حجم كائن.

على سبيل المثال:

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"

إذا كنت تريد المفاتيح التي لم يتم الإشارة إليها من الكائنات الأخرى إلى أن يتم جمعها من القمامة, النظر في استخدام WeakMap بدلا من الخريطة.

وبما أن كل كائن في JS يتصرف مثل - ويتم تنفيذه بصفة عامة - على جدول هاش، أنا مجرد الذهاب مع ذلك ...

var hashSweetHashTable = {};

وذلك في 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
}
يحتوي

وجوه C # القاموس أساليب مفيدة مثل dictionary.ContainsKey() في جافا سكريبت يمكننا استخدام hasOwnProperty مثل

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

إذا كنت تحتاج إلى المفاتيح الخاصة بك أن يكون أي كائن بدلا من مجرد سلاسل ثم يمكنك استخدام بلدي jshashtable.

أنا خلقت هذا لتحقيق بعض المشاكل, مثل مفتاح كائن رسم الخرائط ، قدرة التعداد (مع 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()
    مسح كافة hashtable ، وإزالة كل المفاتيح والقيم.

  • indexOfKey(key)
    عوائد مؤشر المفتاح المحدد ، على أساس إضافة النظام.
    المعلمات:
    key:المفتاح الذي على المؤشر.

  • indexOfValue(value)
    يعود مؤشر القيمة المحددة على أساس إضافة النظام.
    المعلمات:
    value:القيمة التي تحصل على المؤشر.
    ملاحظات:
    هذه المعلومات يتم استردادها من قبل indexOf() طريقة صفيف ، لذا فإنه يقارن كائن فقط مع toString() الأسلوب.

  • entryAt(index)
    بإرجاع كائن مع اثنين من الخصائص:مفتاح وقيمة يمثل الدخول في الفهرس المحدد.
    المعلمات:
    index:مؤشر الدخول للحصول على.

  • containsKey(key)
    عوائد سواء hashtable يحتوي على المفتاح المحدد.
    المعلمات:
    key:مفتاح الاختيار.

  • containsValue(value)
    عوائد سواء hashtable يحتوي على القيمة المحددة.
    المعلمات:
    value:قيمة للتحقق.

  • forEach(iterator)
    تتكرر كل الإدخالات في المحدد iterator.
    المعلمات:
    value:الأسلوب مع 3 معلمات: key, value و index, حيث index يمثل مؤشر الإدخال.

    خصائص:

  • length (للقراءة فقط)
    يحصل على عدد الإدخالات في hashtable.

  • keys (للقراءة فقط)
    يحصل على مجموعة من المفاتيح في hashtable.

  • values (للقراءة فقط)
    يحصل على مجموعة من القيم في hashtable.

  • entries (للقراءة فقط)
    يحصل على مجموعة من كافة الإدخالات في hashtable.إنهم ممثلة في نفس النموذج من طريقة entryAt().

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

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

يمكنك إنشاء واحد باستخدام كما يلي:

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)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top