将事件存储在数组中

时间:2014-08-01 07:40:13

标签: javascript arrays count

我正在寻找一种有效的方法来计算元素的出现次数。 我在循环中读取数据,并且在每个步骤中我都希望在结果数组中增加正确的对象元素,或者创建一个新对象元素(如果它尚不可用)。

我必须处理大量数据,所以我需要一个快速的解决方案。这是一个工作版本:

var hugeDataObject = [
    {id: '1234', dark: true},
    {id: '5678', dark: true},
    {id: '91011', dark: true},
    {id: '91011', dark: false}
];
var ids = [];
var darks = [];
var allIds = [];
var allDarks = [];
  hugeDataObject.forEach(function(attrs) {
    var index = allIds.indexOf(attrs.id);
    if(index >= 0) ids[index].amount += 1;
    else {
      ids.push({type: attrs.id, amount: 1}); 
      allIds.push(attrs.id);
    }

    var index = allDarks.indexOf(attrs.dark);
    if(index >= 0) darks[index].amount += 1;
    else {
      darks.push({type: attrs.dark, amount: 1}); 
      allDarks.push(attrs.dark);
    }
  });

Fiddle 但我有更多的类型,我需要计算,所以变量太多了。

结果:

ids = [
  {type: '1234', amount: 1},
  {type: '5678', amount: 1},
  {type: '91011', amount: 2}
]

darks = [
  {type: true, amount: 3},
  {type: false, amount: 1}
]

(如果你使用loDash,没关系)

提前致谢!

4 个答案:

答案 0 :(得分:1)

如何存储更简单的结构:

var objects = {};
objects['id1234'] = 384;
objects['id5678'] = 955;
objects['id91011'] = 1510;

/* increment */
objects['id1234']++;

答案 1 :(得分:1)

var counter = {};
hugeDataObject.forEach(function(attrs) {
    if (counter[attrs.id]) {
        counter[attrs.id]++;
    }
    else {
        counter[attrs.id] = 1;
    }
});

或者如果你需要数组:

var counts = [];
var indexMap = {};

var i = 0;
indexMap[0] = -1;

hugeDataObject.forEach(function(attrs) {

    var index = indexMap[attrs.id];

    if (index == undefined) {
        indexMap[attrs.id] = i;
        counts[i] = { id: attrs.id, amount: 1 };
        i++;
    }
    else {
        var existingCounter = counts[index];
        existingCounter.amount++;
    }
});

答案 2 :(得分:0)

如果我理解你的观点,那么你试试这个:

 var ids = [];
  var allIds = [];
  hugeDataObject.forEach(function(attrs) {
    var index = allIds.indexOf(attrs.id);
    if(index >= 0){
      ids[index].amount = ids[index].amount + 1;

    } else {
      ids.push({type: attrs.id, amount: 1}); 
      allIds.push(attrs.id);
      // Here first should check is this type available, 
      // after create it or increase the amount
    }
  });

  console.log(ids);

答案 3 :(得分:-1)

这不是太简单,但我明白了。

var getObjectBy = function(base, id, array) {
    for (var i = 0, len = array.length; i < len; i++) {
        if (array[i][base] === id) return array[i];
    }
    return null;
};

var hugeDataObject = [
    {id: '1234', dark: true},
    {id: '5678', dark: true},
    {id: '91011', dark: true},
    {id: '91011', dark: false}
];
var ids = [];
var darks = [];
hugeDataObject.forEach(function(attrs) {
    var index = getObjectBy('type', attrs.id, ids);
    if (index === null) ids.push({type: attrs.id, amount: 1});
    else index.amount += 1;

    var index = getObjectBy('type', attrs.dark, darks);
    if (index === null) darks.push({type: attrs.dark, amount: 1});
    else index.amount += 1;
});

Updated Fiddle

也许它不太漂亮,但我觉得有效。如果你知道更好的方法,那就写下来吧,我会接受的!

谢谢你的答案!