2013-03-14 110 views
1

我有一個日誌分析腳本來填充複雜的可視化。使用jquery搜索對象數組

圖片的陣列(稱爲,而unoriginally,「登錄」)活動的對象,其中每一個是在以下形式:在陣列中

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

將有高達75的活動對象,每片含一系列400-600個動作(從前一天的午夜開始每隔5分鐘一個時隙)。

給定一個已知的活動名稱(上面的foo)和活動數組中已經存在的時間,我需要更新關聯的動作。

每個名稱都是唯一的,每次在數組中以5分鐘的增量升序排列。

因爲每次更新圖表時(因此平均需要更新1000個值和1000 * 500 * 60點圖表),我必須要做1000次以上的操作,所以性能是一個相當關鍵的問題。

在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"; 

這似乎是工作,但它採取了我這麼久,我有這麼多與我自己的論點,我不自信。

我錯過了一個更好的方法嗎?

+0

*「在JQ循環是遠遠超過任何我能寫......更有效的」 *爲什麼地球上,你認爲呢? – 2013-03-14 05:35:32

+0

你可以給時間序列的樣本值 – 2013-03-14 05:35:35

+0

在本地格式如所有字符串「2013年3月13日上午09時40分○○秒」 – PerryW 2013-03-14 05:53:22

回答

2

我不會給你更好的loop method爲你的問題米,因爲你想出的任何迴路將相對不會比最後一個更好。

如果您真的想要一個能夠提高性能的解決方案,那麼您應該考慮徹底重新整理對象。如果每個活動數組的每個日誌和time的每個name都是唯一的,則可以更改對象設置以使這些值爲the key of each subobject

使用這種方法,你只在做一鍵查找,沒有循環需要。

新的日誌對象

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

好像你想要第一個匹配的日誌的第一個匹配的活動。

在這種情況下,您應該在找到第一個匹配項後打破循環。你可以用.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; 
      } 
     } 
    } 
} 
+0

嗯......這與我幾個小時以前的事情沒有任何的距離,我猜想缺乏信心--JQuery很容易成爲一個安全保護毯:) – PerryW 2013-03-14 05:57:41

+0

@PerryW:關鍵是要停止儘快循環*(假設您只對每個數組的第一個結果感興趣)*。你確定你想要在第一場比賽中總是想停止外部陣列嗎?就像如果內部數組沒有找到匹配,你要保持外陣去,或者是在外部陣列中的所有項目獨特之處? – 2013-03-14 06:00:53

+0

...無論如何,我更新了我的答案來說明如何做到這一點,如果外環應繼續在沒有匹配的內循環中找到。 – 2013-03-14 06:07:26