3

我想为 JavaScript 对象及其属性计数实现大小限制。我需要的是在将新属性添加到对象时删除最旧的更新。

考虑以下对象,我计算文本中每个字母(但仅针对最近看到的 2 个字母)的出现次数:

var occurrences = {a: 1, d: 2}

当我阅读时,a我会加occurrences['a']一。但在那之后,如果我看到h我必须删除d,因为它的更新时间比a. 然后,我的对象将如下:

{a: 2, h: 1}

为此目的使用对象是有充分理由的,例如,我不能使用排序数组,因为性能非常重要。

4

2 回答 2

3

确定“最旧”的唯一可靠方法是保留某种索引,可能使用数组。每当您更新对象时,您都会检查该属性是否存在或不使用propertyName in Object. 如果是,则从数组中拼接它并使用 unshift 将它放在索引 0 处,然后在对象上更新它的值。

如果它不存在,并且数组长度等于最大属性计数,pop则数组中最旧的属性名称,unshift索引为 0 的新属性,delete对象中的旧属性并添加新属性。

如果它不存在并且数组长度小于最大属性计数,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 来说会很慢。

于 2013-05-24T14:25:21.727 回答
2

如果您在 node.js 中,您可以利用对象属性的一个令人惊讶的特性:它们按照添加的顺序返回。所以你可以定义一个具有一些属性的对象:

var array = { fake1: 'fake', fake2: 'fake' };

然后每次添加新属性时,都会删除第一个:

for (var i in array) {
  delete array[i];
  break;
}

当您更新属性时,您必须将其删除,然后重新添加它,以便它再次出现在最后。

它简单但非常有效:您的对象中将始终拥有最新的两个属性。每次对元素进行操作时,您都不需要保留额外的数据或检查属性集。

我没有使用浏览器内的 JavaScript 引擎对此进行测试;您不应该依赖属性的顺序,因为该语言不做任何保证,但显然它也有效。

于 2013-05-25T09:34:56.007 回答