1

我有一个代表队列的对象,我想保留最后的第 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;

问题或问题是如果这有内存泄漏,未使用的项目会发生什么?

4

4 回答 4

0

First of all, it'd be much easier if you'd just use an array instead of an object, because you can take advantage of the native splice() method. But to answer your question:

delete m.t1;
delete m.t2;
于 2013-04-26T11:59:06.573 回答
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根据存储为属性名称中第一个字符之后的字符的整数去除除前五个元素之外的所有元素。

这里的 main 函数比较通用,它允许您选择如何将索引转换为排序键,并让您选择保留多少。它返回一个函数,然后你可以在添加新元素时调用你的对象(或者尽可能频繁,我想。)

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

于 2013-04-26T13:36:16.577 回答
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"}
于 2013-04-26T13:59:41.663 回答
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);
于 2013-04-26T11:57:08.077 回答