使用jquery搜索对象数组

时间:2013-03-14 05:33:08

标签: javascript jquery

我有一个日志分析脚本来填充复杂的可视化。

描绘一个活动对象的数组(称为非常原始的'log'),每个对象的格式如下:

{
 name:foo,
 activities:[
             {time:t, action:a},
             {time:t, action:a},
             {time:t, action:a},
             ...
            ]
}

阵列中最多有75个活动对象,每个活动对象包含400-600个动作的数组(自前一天午夜起每5分钟一个时段)。

如果已知活动名称(上面的foo)和活动数组中已存在的时间,我需要更新相关的操作。

每个名称都是唯一的,每次在数组中按升序排列,精确增加5分钟。

每次更新图表时我必须做1000多次这样的事情(所以平均需要更新1000个值,1000 * 500 * 60点才能绘图),性能是一个相当关键的问题... < / p>

在jq中循环远比我能写的任何东西都高效,所以目前我已经

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

$.grep($.grep(log, function(n, i)
 {
  return (n.name == n)
  }
  )[0].activities, function(n, i) 
  {
   return (n.time == t)
  }
 )[0].action = "bar";

这似乎有效,但这花了我很长时间,我和自己有太多争论,我不自信。

我错过了更好的方法吗?

2 个答案:

答案 0 :(得分:2)

我不会为您的问题提供更好的loop method,因为您提出的任何循环相对都不会比最后一个更好。

如果您真的想要一个可以提高性能的解决方案,那么您应该考虑完全重新排列对象。如果每个日志的每个name和每个活动数组的time都是唯一的,则可以更改对象设置,使其值为the key of each subobject

使用这种方法,你只需要进行按键查找,不需要循环。

新LOG对象

  var log =
    {
      unique_name : {
        "activities" : {
          time_1 : action_1,
          time_2 : action_2,
          time_3 : action_3,
          etc...
        }
      },
      unique_name_2 : {
        "activities" : {
          etc...
        }
      }
    }

现在使用var u_name = "foo";var t = "some time";,您只需执行...

log[u_name][t] = "some action";

希望这有帮助!

答案 1 :(得分:1)

好像你想要第一个匹配日志的第一个匹配活动。

在这种情况下,您应该在找到第一个匹配后中断循环。您可以使用.some()

执行此操作
n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

log.some(function(ob, i) {
  if (ob.name == n) {
      ob.activities.some(function(ob2, i)  {
          if (ob2.time == t) {
              ob2.action = "bar";
              return true;
          }
      });
      return true;
  }
});

此外,您的n参数遮蔽了您的n变量,因此我将参数更改为ob


for循环通常比功能方法快一点。

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

for (var i = 0; i < log.length; i++) {
  var ob = log[i];
  if (ob.name == n) {
      for (var j = 0; j < ob.activities.length; j++) {
          var ob2 = ob.activities[j];
          if (ob2.time == t) {
              ob2.action = "bar";
              break;
          }
      }
      break;
  }
}


如果您认为如果内循环上找不到匹配项,您应该保持外循环,请将代码更改为以下之一:

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

log.some(function(ob, i) {
  if (ob.name == n) {
      return ob.activities.some(function(ob2, i)  {
          if (ob2.time == t) {
              ob2.action = "bar";
              return true;
          }
      });
  }
});

n = "foo";
t = new Date(y,mm,d,h,m).toLocaleString() // matches a time stamp in the log

OUTER:
for (var i = 0; i < log.length; i++) {
  var ob = log[i];
  if (ob.name == n) {
      for (var j = 0; j < ob.activities.length; j++) {
          var ob2 = ob.activities[j];
          if (ob2.time == t) {
              ob2.action = "bar";
              break OUTER;
          }
      }
  }
}