我想在javascript中实现哈希表,但它有一个例外

时间:2017-08-22 08:46:40

标签: javascript hashtable

$array=array('One','Two','Two','Three','Four','Five','Five','Six');

$new_array= array_count_values($array);

foreach($new_array as $key=>$val){

  if($val>1){

     for($j=0;$j<$val;$j++){

         echo "<span style='color:red'>".$key."</span>";
     }

   }else{

     echo "<span>".$key."</span>";

   }

}

我想在javascript中实现哈希表,但是当我测试它时,会出现这样的异常:

未捕获的ReferenceError:未定义containsKey     在HashTable.add(:8:3)     at:64:10

2 个答案:

答案 0 :(得分:0)

使用this.containsKey代替,因为containsKeyHashTable创建的对象内的'成员'方法,您必须使用this引用它。

function HashTable(){
    var size = 0;
    var entry = new Object();
    
    this.containsValue = function(value){
        for(var prop in entry){
            if(entry[prop] == value){
                return true;
            }
        }
        return false;
    }
    
    this.add = function(key,value){
        if(!this.containsKey(key)){
            size++;
        }
        entry[key] = value;
    }

this.getValue = function(key){
    return this.containsKey(key)?entry[key]:null;
}

this.remove = function(key){
    if (this.containsKey(key) && delete entry[key]) {
        size--;
    }
}

this.containsKey = function(key){
    return (key in entry);
}


//get all values
    this.getValues = function(){
        var values = new Array();
        for(var prop in entry){
            values.push(entry[prop]);
        }
        return values;
    }
//get all keys
    this.getKeys = function(){
        var keys = new Array();
        for(var prop in entry){
            values.push(prop);
        }
        return keys;
    }
this.getSize = function(){
    return size;
}

this.clear = function(){
    size = 0;
    entry = new Object;//???????????????????
}
}

var hashtest = new HashTable(); hashtest.add('name','LiMing');
console.log(hashtest.getValues())

使用ES6组织代码有一种更好的方法:

class HashTable {
  constructor() {
    this.size = 0;
    this.entry = new Object();
  }
  
  containsValue(value) {
    for(var prop in entry){
      if(this.entry[prop] == value){
        return true;
      }
    }
    return false;
  }
  
  add(key,value) {
    if(!this.containsKey(key)){
      this.size++;
    }
    this.entry[key] = value;
  }
  
  getValue(key) {
    return this.containsKey(key) ? this.entry[key] : null;
  }
  
  remove(key) {
    if (this.containsKey(key) && delete this.entry[key]) {
      size--;
    }
  }
  
  containsKey(key) {
    return (key in this.entry);
  }
  
  //get all values
  getValues() {
    var values = new Array();
    for(var prop in this.entry){
      values.push(this.entry[prop]);
    }
    return values;
  }
  
  //get all keys
  getKeys() {
    var keys = new Array();
    for(var prop in this.entry){
      values.push(prop);
    }
    return keys;
  }
  
  getSize() {
    return this.size;
  }
  
  clear() {
    this.size = 0;
    this.entry = new Object();//???????????????????
  }
  
}


var hashtest = new HashTable(); hashtest.add('name','LiMing');
console.log(hashtest.getValues())

答案 1 :(得分:0)

您遇到的问题是scope的问题。 javascript解释器不知道你的意思是来自HashTable类的containsKey

在类范围内调用函数时,请务必使用“this”引用它们。因此containsKey应引用为this.containsKey(key)。这样,解释器就知道你指的是类的范围而不是本地范围。

您还应该对具有类范围的变量执行此操作。因此,当您执行size++时,您应该实际编写this.size++entry也是如此。如果你不添加“this”,它将假定它是在该函数本身内定义的局部函数或变量。

所以你应该把你的add()函数重写为

this.add = function(key,value){
        if(!this.containsKey(key)){
            this.size++;
        }
        this.entry[key] = value;
    }

为什么要手动跟踪大小呢?您可以简单地将“entry”定义为数组并使用this.entry.size

考虑到hashmap的更具体的情况,我建议你简单地在对象中创建两个数组,一个用于键,一个用于值,这将大大简化你的问题,因为你可以简单地使用内置Javascript数组函数。两个数组都有一个数字索引,但键和值都将始终具有相同的索引,因此您可以轻松地对它们进行数学计算。结果是这样的:

function HashTable() {
  this.keys = new Array();
  this.values = new Array();

  this.add = function(key, value) {

    if (this.containsKey(key)) {
      var index = this.keys.indexOf(key);
      this.values[index] = value;
    } else {
      this.keys.push(key);
      this.values.push(value);
    }
  }

  this.containsKey = function(key) {
    return this.keys.includes(key);
  }

  this.containsValue = function(value) {
    return this.values.includes(value);
  }

  this.get = function(key) {
    var index = this.keys.indexOf(key);
    return this.values[index];
  }

  this.remove = function(key) {
    if (this.containsKey(key)) {
      var index = this.keys.indexOf(key);
      this.keys.splice(index, 1);
      this.values.splice(index, 1);
    }
  }

  this.size = function() {
    return this.keys.length;
  }

  this.clear = function() {
    this.keys = new Array();
    this.values = new Array();
  }
}

// Create hashtable
var hashTable = new HashTable();

// Add some test data
hashTable.add('name', 'LiMing');
hashTable.add('location', 'At home');
hashTable.add('eyes', 'blue');

// Updates the value, doesn't add it
hashTable.add('eyes', 'brown');
console.log(hashTable.get("eyes"));

// Get the size
console.log(hashTable.size());

// Check if a value or key is in the hashtable
console.log(hashTable.containsValue("test")); // False
console.log(hashTable.containsValue("LiMing")); // True
console.log(hashTable.containsKey("name")); // True
console.log(hashTable.containsKey("age")); // False

// Get all the keys and values
console.log(hashTable.keys);
console.log(hashTable.values);

// Remove an item
hashTable.remove('eyes');
console.log(hashTable.keys);
console.log(hashTable.values);

// Clear hashtable
hashTable.clear();
console.log(hashTable.keys);
console.log(hashTable.values);