JavaScript对象属性计数限制,删除最早更新的属性

3
我希望对JavaScript对象及其属性数量设置大小限制。当向对象添加新属性时,我需要删除最旧的更新内容。
考虑以下对象,我在文本中计算每个字母出现的次数(但仅针对最近看到的2个字母):
var occurrences = {a: 1, d: 2}
当我读取a时,我将通过增加occurrences ['a']来增加一个。但是,在此之后,如果我见到h,那么我必须删除d,因为它比a更久远地更新了。 然后,我的对象将如下所示:
{a: 2, h: 1}
使用对象进行此操作有很好的原因,因此我不能使用排序数组,例如,性能非常重要。

我认为跟踪所有的属性会损害你的性能。 - Ven
2个回答

3
确定“最老”的唯一可靠方法是保持某种索引,可能使用数组。每当更新对象时,您都可以使用propertyName in Object检查属性是否存在。如果是,则从数组中拼接它,并使用unshift将其放在索引0处,然后在对象上更新其值。
如果它不存在,并且数组长度等于最大属性数,则从数组中弹出最旧的属性名称,使用unshift将新属性放在索引0处,从对象中删除旧属性并添加新属性。
如果它不存在并且数组长度小于最大属性计数,则使用unshift将名称添加到数组中以将其添加到索引0处,并将其添加到对象中。

编辑

一些代码。请注意,您需要防止覆盖*_maxPropCount*和*_index*属性,我会留给您。
var o = {a:1, b:2, _maxPropCount: 2, _index: ['a','b']};

function updateObject(obj, prop, value) {
  var idx = obj._index;
  var i, lastProp;

  // If property exists, move to start of index array
  if (prop in obj) {
    i = idx.indexOf(prop);
    idx.unshift(idx.splice(i, 1));

  // Otherwise, property doesn't exist so check length and
  // number of properties
  } else {

    // If already have full count, pop last property name from end of array
    // and delete from object
    if (idx.length == o._maxPropCount) {
      lastProp = idx.pop();
      delete o[lastProp];
    }

    // Update index
    idx.unshift(prop);
  }

  // Update object
  obj[prop] = value;
}

updateObject(o, 'b', 6);
alert(o._index + ' ' + o.b); // b,a 6

updateObject(o, 'g', 2);
alert(o._index + ' ' + o.a); // g,b undefined

代码可以缩短几行,但这并不会使其更快。哦,indexOf是ES5的,因此在旧浏览器上不可用,需要使用一个shim,对于需要使用它的UA来说会很慢,如果你有许多属性。

是的,那也是我首先尝试的(然后看它的性能如何)。而且我认为你的解释已经足够详细了(+1),用一些基本的JS知识将其转换为代码应该很容易。 - CBroe

2
如果您在使用node.js,您可以利用对象属性的一个令人惊讶的特性:它们按照添加的顺序返回。因此,您只需定义一个带有几个属性的对象即可:
var array = { fake1: 'fake', fake2: 'fake' };

然后,每次添加新属性时,您都会删除第一个属性:
for (var i in array) {
  delete array[i];
  break;
}

当你更新一个属性时,需要先将其删除,然后重新添加,以便它再次排在最后。
这很简单但非常有效:你的对象中始终会有最新的两个属性。你不需要保留额外的数据或每次操作元素时都遍历属性集。
我还没有在浏览器JavaScript引擎中测试过这个方法;你不应该依赖属性的顺序,因为语言并不保证,但显然这也可以工作。

但是如果您更新一个属性,属性顺序不会被修改,因此对于我的目的没有用处。 - sgmonda
你是对的,你必须删除然后重新添加该属性。我正在更新我的回答。 - alexfernandez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接