2013-04-26 44 views
1

我有一個表示隊列的對象,並且我想保留它的最後n個元素(固定大小)。如何保留JavaScript對象(固定隊列)的最後N個屬性

var m = {}; 
m["t1"] = { a: "t1", b: "t1" }; 
m["t2"] = { a: "t2", b: "t2" }; 

...... 
...... 
m["tn-1"] = { a: "tn-1", b: "tn-1" }; 
m["tn"] = { a: "tn", b: "tn" }; 

在這個例子中,我想保留最後的N並刪除其餘的。

什麼是簡單的解決方案?可以用下劃線js來完成?

作爲「@AlexK注意到,」的for..in對象的順序在技術上不能保證匹配添加順序

編輯:

我發現一種解決方案:

m2= {}; 

_.each(_.last(_.keys(m), size), function(key){ 
    m2[key] = m[key]; 
}); 

m= m2; 

問題或問題是如果這有內存泄漏,未使用的項目會發生什麼?

+0

廣東話,你剛剛從相反的順序循環,並刪除所有元素想到第一次和第二次(我的意思是最後的2個值)? – dreamweiver 2013-04-26 11:56:39

+2

for..in對象的順序在技術上不能保證與添加的順序相匹配 – 2013-04-26 11:57:23

+0

如果你保留最後2個,那麼當你添加一個新的{a:b}時你想要發生什麼?將它存儲在最後2個或之後? – 2013-04-26 12:09:47

回答

0

這是一個潛在的本土保持名稱索引/鍵的方式,但追蹤如果不使用真正數組則需要添加的順序。

trimToLast丟棄頂部項目並調整剩餘項目的索引。

它使用a作爲關鍵字,並用相同的值替換現有的任何現有項目。 後續添加出現在對象的末尾。

function Q() { 
    this.length = 0; 
    this.items = {}; 
}; 
Q.prototype.add = function(a, b) { 
    this.items[a] = {index: typeof this.items[a] === "undefined" ? this.length++ : this.items[a].index, a: a, b: b}; 
    return this; 
} 
Q.prototype.trimToLast = function(keepLast) { 
    this.length -= keepLast; 
    for (var i in this.items) { 
     if (this.items[i].index < this.length) { 
      delete this.items[i]; 
     } else { 
      this.items[i].index -= this.length; 
     } 
    } 
    this.length = keepLast; 
} 

var q = new Q(); 
q.add("t1", "t1").add("t2", "t2"); 
q.add("t3", "t3"); 
q.add("t4", "t4"); 

q.trimToLast(2); 

q.add("t5", "t5"); 

for (var i in q.items) 
    console.log(i, ": #" + q.items[i].index + " of " + q.length, q.items[i]); 

對於

t3 : #0 of 3 Object {index: 0, a: "t3", b: "t3"} 
t4 : #1 of 3 Object {index: 1, a: "t4", b: "t4"} 
t5 : #2 of 3 Object {index: 2, a: "t5", b: "t5"} 
0

好吧,這是你想要什麼,如果你的名字所有的時間你的指標像TXXXX XXXX是一個數字:

function keepWhereTIsSuperiorAt(number,obj) 
{ 
    for (var property in obj) { 
     if(property.substring(1) <= number) 
      delete obj[property];  
    } 
} 

keepWhereTIsSuperiorAt(2,m); 
console.log(m); 
+0

這將需要計算正確的基數,這仍然涉及檢查所有指數。我想,如果我們確實知道所有指標都會被添加,並且我們知道最新的指標是什麼,那麼這就行得通了。 – 2013-04-26 13:22:52

0

首先,它會是如果你只是使用更容易一個數組而不是一個對象,因爲你可以利用原生的splice()方法。但是,爲了回答你的問題:

delete m.t1; 
delete m.t2; 
0

這裏有一個辦法:

var keepTopFnBuilder = function(count, makeSortKey) { 
    return function(obj) { 
     var keys = _.sortBy(_.map(_.keys(obj), function(key) { 
      return {key: key, sortKey: makeSortKey(key)}; 
     }), "sortKey"); 
     _.each(_.first(keys, Math.max(0, keys.length - count)), function(key) { 
      delete obj[key.key]; 
     }); 
    }; 
}; 

var m = {}; 

var keepTop = keepTopFnBuilder(5, function(key) {return +key.substring(1);}); 

每當keepTop(m)被調用,它會去掉所有但從m的五大要素基於存儲爲後面的字符的整數屬性名稱中的第一個。

這裏的主要功能更具有通用性,因爲它允許您選擇如何將索引轉換爲排序鍵,並讓您選擇保留多少個索引。它返回一個函數,然後就可以在對象上調用,只要你添加新元素(或經常只要你喜歡,我想。)

您可以在工作中看到它http://jsfiddle.net/CrossEye/4M3L4/

相關問題