JavaScript Hashmap Eşdeğer
Net this answer Bu gösterimde: update 3'te yapılmış gibi
var hash = {};
hash[X]
değil aslında karma nesne X
; aslında sadece dönüştürür X
bir dize () .toString()
Eğer bir nesne ya da başka bir built-in dönüşüm için çeşitli ilkel türler) ve sonra görünen dize kadar, karma olmadan, "hash
". Nesne eşitlik de işaretli değil - eğer iki farklı nesne aynı dize dönüşüm, sadece birbirimizin üzerine.
Bu göz önüne alındığında, orada javascript hashmaps herhangi bir etkin uygulamaları. (Örneğin, javascript hashmap
2. Google sonuç O(n) herhangi bir işlem için bir uygulama verir. Çeşitli diğer sonuçları eşdeğer dize temsilleri ile farklı nesnelerin birbirleri üzerine olduğu gerçeğini göz ardı.
CEVAP
Sorun açıklaması
JavaScript yerleşik genel bulunmuyorgöstertürü (bazen denirilişkisel diziyasözlükisteğe bağlı ) tuşları ile rasgele değerler erişim sağlar. JavaScript temel veri yapısınesnesadece kabul eden harita özel bir tür anahtar olarak dizeleri ve prototip miras, alıcıları ve ayarlayıcıları ve biraz daha fazla voodoo gibi özel semantiği vardır.
Ne zaman usings nesneler olarak haritalar, hatırlaman gereken bu anahtarı olacaktır dönüştürülmüş bir dize değeri) toString()
, hangi sonuçlar eşleme 5
'5'
aynı değer ve tüm nesneleri yok üzerine yazma toString()
yöntem için değer endeksli '[object Object]'
. Ayrıca eğer hasOwnProperty()
kontrol bile istemsiz kalıtsal özellikleri erişebilirsiniz.
JavaScript yerleşikdiziyazın bir bit yardımcı olmuyor: JavaScript diziler diziler, ama sadece biraz daha özel özellikleri ile nesneleri ilişkisel değildir. Eğer haritalar olarak kullanılan olamaz neden bilmek istiyorsanız, look here.
Eugene Çözüm
Eugene Lazutkin zaten sözlük bir nesnenin özellikleri olarak ilişkili değerleri aramak için kullanılan benzersiz bir dize oluşturmak için özel bir hash fonksiyonu kullanarak temel fikir nitelendirdi. Bu büyük olasılıkla nesneler şeklinde DAHİLİ olarak uygulanır, çünkü en hızlı çözüm olacaktırhash tabloları.
- Not:Tablo (bazen denir . karma ^em>karma haritalar) göster karma kavramı sayısal değerler üzerinden destek dizi ve bir arama kullanarak belirli bir uygulama. Çalışma zamanı ortamı olabilir kullanın diğer yapılar gibiarama ağaçlarıyalisteler atlayınJavaScript nesneleri uygulamak için, ama nesneler temel veri yapısı olarak, yeterince optimize edilmiş olmalıdır.
Rasgele nesne için benzersiz bir karma değer elde etmek için, bir olasılık, küresel bir karşı kullanmak ve nesne karma değeri kendisi (bir özellik __hash
adlı eg) önbellek.
Bu yaptığı hem de ilkel değerler ve nesneler için çalışan bir hash fonksiyonudur:
function hash(value) {
return (typeof value) ' ' (value instanceof Object ?
(value.__hash || (value.__hash = arguments.callee.current)) :
value.toString());
}
hash.current = 0;
Bu işlev, Eugene tarafından açıklandığı gibi kullanılabilir. Kolaylık sağlamak için, daha fazla Map
sınıf sarın edeceğiz.
* *Benim 20 uygulama
Aşağıdaki uygulama ayrıca her iki anahtar ve değerler üzerinde hızlı yineleme izin vermek için iki kat bağlantılı liste anahtar-değer çiftleri depolamak. Kendi denetim işlevini sağlamak, örnek oluşturma sonra 21* *yöntem üzerine yazabilirsiniz.
// linking the key-value-pairs is optional
// if no argument is provided, linkItems === undefined, i.e. !== false
// --> linking will be enabled
function Map(linkItems) {
this.current = undefined;
this.size = 0;
if(linkItems === false)
this.disableLinking();
}
Map.noop = function() {
return this;
};
Map.illegal = function() {
throw new Error("illegal operation for maps without linking");
};
// map initialisation from existing object
// doesn't add inherited properties if not explicitly instructed to:
// omitting foreignKeys means foreignKeys === undefined, i.e. == false
// --> inherited properties won't be added
Map.from = function(obj, foreignKeys) {
var map = new Map;
for(var prop in obj) {
if(foreignKeys || obj.hasOwnProperty(prop))
map.put(prop, obj[prop]);
}
return map;
};
Map.prototype.disableLinking = function() {
this.link = Map.noop;
this.unlink = Map.noop;
this.disableLinking = Map.noop;
this.next = Map.illegal;
this.key = Map.illegal;
this.value = Map.illegal;
this.removeAll = Map.illegal;
return this;
};
// overwrite in Map instance if necessary
Map.prototype.hash = function(value) {
return (typeof value) ' ' (value instanceof Object ?
(value.__hash || (value.__hash = arguments.callee.current)) :
value.toString());
};
Map.prototype.hash.current = 0;
// --- mapping functions
Map.prototype.get = function(key) {
var item = this[this.hash(key)];
return item === undefined ? undefined : item.value;
};
Map.prototype.put = function(key, value) {
var hash = this.hash(key);
if(this[hash] === undefined) {
var item = { key : key, value : value };
this[hash] = item;
this.link(item);
this.size;
}
else this[hash].value = value;
return this;
};
Map.prototype.remove = function(key) {
var hash = this.hash(key);
var item = this[hash];
if(item !== undefined) {
--this.size;
this.unlink(item);
delete this[hash];
}
return this;
};
// only works if linked
Map.prototype.removeAll = function() {
while(this.size)
this.remove(this.key());
return this;
};
// --- linked list helper functions
Map.prototype.link = function(item) {
if(this.size == 0) {
item.prev = item;
item.next = item;
this.current = item;
}
else {
item.prev = this.current.prev;
item.prev.next = item;
item.next = this.current;
this.current.prev = item;
}
};
Map.prototype.unlink = function(item) {
if(this.size == 0)
this.current = undefined;
else {
item.prev.next = item.next;
item.next.prev = item.prev;
if(item === this.current)
this.current = item.next;
}
};
// --- iterator functions - only work if map is linked
Map.prototype.next = function() {
this.current = this.current.next;
};
Map.prototype.key = function() {
return this.current.key;
};
Map.prototype.value = function() {
return this.current.value;
};
Örnek
Aşağıdaki komut dosyası
var map = new Map;
map.put('spam', 'eggs').
put('foo', 'bar').
put('foo', 'baz').
put({}, 'an object').
put({}, 'another object').
put(5, 'five').
put(5, 'five again').
put('5', 'another five');
for(var i = 0; i < map.size; map.next())
document.writeln(map.hash(map.key()) ' : ' map.value());
bu çıktıyı üretir:
string spam : eggs
string foo : baz
object 1 : an object
object 2 : another object
number 5 : five again
string 5 : another five
İleri değerlendirmeler
PEZ toString()
yöntem üzerine, muhtemelen hash fonksiyonu ile önerdi. Bu temel öğeler için toString()
değişen . ilkel değerler için işe yaramazsa, çünkü mümkün değildir ^em>çokkötü bir fikir). Eğer toString()
keyfi nesneler için anlamlı bir değer döndürmek istiyorsak, bazı insanlar (ben dahil) düşünün Object.prototype
, değiştirmek zorundayızyasak.
< / ^ hr .
Düzenleme:Map
benim uygulama gibi diğer JavaScript güzellikler geçerli sürümü 33**.
Yok C#'In encodeurıcomponent Java...
() JavaScript isset eşdeğer...
'Java eşdeğer'In Thread ler ...
C# String.İsNullOrEmpty Javascript eşd...
Javascript var_dump için bir eşdeğer (...