2013-02-01 104 views
4

我的任務有序映射實現

在我的JavaScript代碼,我經常使用對象的「地圖」鍵的值,所以我可以在以後通過一定的值直接訪問它們。例如:

var helloMap = {}; 
helloMap.de = "Hallo"; 
helloMap["en"] = "Hello"; 
helloMap.es = "Hola"; 

所以我建立通過一步在我的源代碼使用兩個可用符號對象樣式陣列樣式地圖對象的步驟。

後來我可以訪問我通過helloMap["de"]添加的值。因此,如果我不必關心在對象上設置屬性的順序,那就好了。

如果我想現在迭代對象的屬性,據我所知,沒有辦法確保我將按照它們添加的順序迭代它們。

注:我不能使用一些包裝對象,只是在那裏舉行一個數組,然後使用它的方法來添加值,所以是這樣的:

var HelloMap = function(){ 
    this.myMap = []; 
    this.addProperty = function(key, value){ 
    this.myMap.push({key: key, value: value}); 
    } 
} 

或類似的東西不會爲我工作。所以對於使用該對象的程序員來說,解決方案必須是絕對透明的。

這就是說我需要的對象將是一個空對象,它維護添加到它的屬性的順序。像這樣的東西會做:

var helloMap = {}; 
helloMap = getOrderAwareObject(helloMap); 

,這樣的形式helloMap.xy = "foo"helloMap["yz"] = "bar"將在對象跟蹤「以」每進一步分配,

可能的解決方案

因爲我做在下劃線或jQuery中找不到任何解決方案給我這樣一個特殊的對象,我碰到了爲JavaScript對象中的屬性定義getter和setter的可能性,因爲我可以依靠ECMAScript 5標準我可以使用它。

這個問題是,你必須知道在對象被設置之前可以設置的所有可能的屬性。因爲如果你定義它你得到名稱它。

我所尋找的東西就像一個默認吸氣默認二傳手其適用的對象,如果沒有getter和setter已爲屬性定義。所以我可以隱藏排序的地圖後面的對象界面。

  • 在你知道的任何框架中,是否已經有解決方案?
  • 有沒有類似「default getter/setter」的機制?
+0

如果順序很重要,那麼你必須使用一個數組。 –

+0

是的..好..謝謝。但關聯數組的問題在於,它們不能通過我需要的點運算符來訪問。順便說一下......你確定他們甚至保持了他們的訂單嗎? – Chris

+1

Javascript不會執行關聯數組。您可以設置數組屬性,但它們獨立於索引數組項,並且與無格式js對象的屬性相同。 –

回答

6

恐怕你需要一個使用數組的內部封裝器。 ECMAScript 5(這是當前瀏覽器JavaScript實現所基於的標準)根本不允許有序的對象屬性。

但是,ECMAScript 6將有一個Map implementation具有有序的屬性。另見http://www.nczonline.net/blog/2012/10/09/ecmascript-6-collections-part-2-maps/

ECMAScript中6

還可能有其他的選擇,請參閱以下問題:

How can I define a default getter and setter using ECMAScript 5?

+0

無法預先添加到ES6 Map類型的權利? –

3

我不知道一個通​​用的解決方案,但非一般的解決方案是非常簡單的構造。

通常,您維護一個對象數組,其中包含幾個定義爲數組屬性的方法。至少,這是我的方法。

下面是從一個更大的應用爲例,採取(以修飾的形式):

var srcs = []; 
srcs.find = function(dist) { 
    var i; 
    for(i=0; i<this.length; i++) { 
     if(dist <= this[i].dist) { return this[i]; } 
    } 
    return null; 
}; 
srcs.add = function(dist, src) { 
    this.push({ dist:dist, src:src }); 
} 
srcs.remove = function(dist) { 
    var i; 
    for(i=0; i<this.length; i++) { 
     if(this[i].dist === dist) { 
      srcs.splice(i,1); 
      return true; 
     } 
    } 
    return false; 
}; 
srcs.add(-1, 'item_0.gif'); 
srcs.add(1.7, 'item_1.gif'); 
srcs.add(5, 'item_2.gif'); 
srcs.add(15, 'item_3.gif'); 
srcs.add(90, 'item_4.gif'); 

不幸的是,你失去了一個簡單的JS對象查找的簡單,但是這是你付出的代價爲具有有序實體。

如果你絕對必須有秩序和dot.notation,然後維持一個普通JS對象查找訂單的數組。小心謹慎,這兩者可以保持完整的完整性。

+1

感謝您的最後提示!同時維護一個對象和一個數組對我的具體情況來說似乎是一個很好的「現在」解決方案。 – Chris

4

添加鏈接到自定義JavaScript庫,該庫提供Sorted地圖和其他實現,以供將來在此主題中參考。退房https://github.com/monmohan/dsjslib -msingh

+0

這看起來很有用。感謝發佈。我也發現了這個(http://www.collectionsjs.com/sorted-map),但文檔不清楚,API令人困惑(例如set(key,value)vs add(value,key))和as結果,我很難相信實現 – i8abug

0

看到我對this問題的回答。我實現了一個基本的有序哈希表(ES 5+只,沒有刻意去填充工具)

-1
var put = function(k,v){ 
if(map[k]){ 
    console.log("Key "+ k+" is already present"); 
}else 
{ 
    var newMap = {}; 
    map[k] = v; 
    Object.keys(map).sort().forEach(function(key){ 
    newMap[key] = map[key]; 
}); 
    map = newMap; 
    //delete newMap; in case object memory need to release 
    return map; 
} 
} 

Put方法將總是一個鍵值對,在內部創建另一個地圖與實際地圖,更新排序鍵該值並返回帶有排序鍵的更新地圖。無需外部庫包含。

+0

堆棧溢出是一個很好的做法,爲解決方案的工作原理添加一個解釋。有關更多信息,請閱讀[如何回答](// stackoverflow.com/help/how-to-answer)。 –