Ily*_*man 37 javascript hash key object
我想创建一个哈希表,将我的对象作为他的密钥,而不将其转换为String.
有点像这样:
var object1 = new Object();
var object2 = new Object();
var myHash = new HashTable();
myHash.put(object1, "value1");
myHash.put(object2, "value2");
alert(myHash.get(object1), myHash.get(object2)); // I wish that it will print value1 value2
Run Code Online (Sandbox Code Playgroud)
编辑:请参阅我的答案以获得完整的解决方案
Pet*_*ter 22
这是一个简单的Map实现,可以使用任何类型的键,包括对象引用,它不会以任何方式改变键:
function Map() {
var keys = [], values = [];
return {
put: function (key, value) {
var index = keys.indexOf(key);
if(index == -1) {
keys.push(key);
values.push(value);
}
else {
values[index] = value;
}
},
get: function (key) {
return values[keys.indexOf(key)];
}
};
}
Run Code Online (Sandbox Code Playgroud)
虽然这会产生与哈希表相同的功能,但它实际上并没有使用哈希函数实现,因为它迭代数组并且具有最差的O(n)性能.但是,对于绝大多数明智的用例而言,这根本不应成为问题.该indexOf功能由JavaScript引擎实现,并且经过高度优化.
Flo*_*ine 18
这是一个提议:
function HashTable() {
this.hashes = {};
}
HashTable.prototype = {
constructor: HashTable,
put: function( key, value ) {
this.hashes[ JSON.stringify( key ) ] = value;
},
get: function( key ) {
return this.hashes[ JSON.stringify( key ) ];
}
};
Run Code Online (Sandbox Code Playgroud)
API完全如您的问题所示.
但是你不能在js中使用引用(因此两个空对象看起来与hashtable相同),因为你无法得到它.有关更多详细信息,请参阅此答案:如何获取javascript对象引用或引用计数?
Jsfiddle演示:http://jsfiddle.net/HKz3e/
但是,对于事物的独特方面,您可以使用原始对象,就像这样:
function HashTable() {
this.hashes = {},
this.id = 0;
}
HashTable.prototype = {
constructor: HashTable,
put: function( obj, value ) {
obj.id = this.id;
this.hashes[ this.id ] = value;
this.id++;
},
get: function( obj ) {
return this.hashes[ obj.id ];
}
};
Run Code Online (Sandbox Code Playgroud)
Jsfiddle演示:http://jsfiddle.net/HKz3e/2/
这意味着您的对象需要具有一个id您不会在其他地方使用的属性.如果你想让这个属性不可枚举,我建议你看看defineProperty(它不是跨浏览器,但是,即使使用ES5-Shim,它在IE7中也不起作用).
这也意味着您可以在此哈希表中存储的项目数量受限.限于2 53,即.
现在,"它无法在任何地方工作"解决方案:使用ES6 WeakMaps.它们完全是为了这个目的而完成的:将对象作为键.我建议您阅读MDN以获取更多信息:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/WeakMap
它与你的API略有不同(它是set和不是put):
var myMap = new WeakMap(),
object1 = {},
object2 = {};
myMap.set( object1, 'value1' );
myMap.set( object2, 'value2' );
console.log( myMap.get( object1 ) ); // "value1"
console.log( myMap.get( object2 ) ); // "value2"
Run Code Online (Sandbox Code Playgroud)
带有弱地图垫片的Jsfiddle演示:http://jsfiddle.net/Ralt/HKz3e/9/
但是,弱映射是在FF和Chrome中实现的(仅当您在chrome中启用"实验性javascript功能"标志时).有垫片可用,如下所示:https://gist.github.com/1269991.使用风险由您自己承担.
您也可以使用Maps它们,它们可能更适合您的需求,因为您还需要将原始值(字符串)存储为键.Doc,Shim.
Ily*_*man 11
我把@Florian Margaine的建议提升到了更高的水平,并想出了这个:
function HashTable(){
var hash = new Object();
this.put = function(key, value){
if(typeof key === "string"){
hash[key] = value;
}
else{
if(key._hashtableUniqueId == undefined){
key._hashtableUniqueId = UniqueId.prototype.generateId();
}
hash[key._hashtableUniqueId] = value;
}
};
this.get = function(key){
if(typeof key === "string"){
return hash[key];
}
if(key._hashtableUniqueId == undefined){
return undefined;
}
return hash[key._hashtableUniqueId];
};
}
function UniqueId(){
}
UniqueId.prototype._id = 0;
UniqueId.prototype.generateId = function(){
return (++UniqueId.prototype._id).toString();
};
Run Code Online (Sandbox Code Playgroud)
用法
var map = new HashTable();
var object1 = new Object();
map.put(object1, "Cocakola");
alert(map.get(object1)); // Cocakola
//Overriding
map.put(object1, "Cocakola 2");
alert(map.get(object1)); // Cocakola 2
// String key is used as String
map.put("myKey", "MyValue");
alert(map.get("myKey")); // MyValue
alert(map.get("my".concat("Key"))); // MyValue
// Invalid keys
alert(map.get("unknownKey")); // undefined
alert(map.get(new Object())); // undefined
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
48134 次 |
| 最近记录: |