2010-06-10 76 views
2

的假設你有一個具有兩個功能Django視圖:比較兩個大集合屬性

第一個函數使用XSLT樣式表使一些XML,併產生一個div 1000級的子元素是這樣的:

<div id="myText"> 
    <p id="p1"><a class="note-p1" href="#" style="display:none" target="bot">✽</a></strong>Lorem ipsum</p> 
    <p id="p2"><a class="note-p2" href="#" style="display:none" target="bot">✽</a></strong>Foo bar</p> 
    <p id="p3"><a class="note-p3" href="#" style="display:none" target="bot">✽</a></strong>Chocolate peanut butter</p> 
    (etc for 1000 lines) 
    <p id="p1000"><a class="note-p1000" href="#" style="display:none" target="bot">✽</a></strong>Go Yankees!</p> 
</div> 

<div id="myNotes"> 
    <p id="n1"><cite class="note-p1"><sup>1</sup><span>Trololo</span></cite></p> 
    <p id="n2"><cite class="note-p1"><sup>2</sup><span>Trololo</span></cite></p> 
    <p id="n3"><cite class="note-p2"><sup>3</sup><span>lololo</span></cite></p> 
    (etc for n lines) 
    <p id="n"><cite class="note-p885"><sup>n</sup><span>lololo</span></cite></p> 
</div> 

我需要看到哪些元素在#myText具有類:

第二功能使用另一樣式表,以產生這樣一個div呈現另一個XML文檔與#myNotes中的元素匹配並顯示它們。我可以使用下面的jQuery的做到這一點:

$('#myText').find('a').each(function() { 
    var $anchor = $(this); 
    $('#myNotes').find('cite').each(function() { 
     if($(this).attr('class') == $anchor.attr('class')) { 
      $anchor.show(); 
    }); 
}); 

然而,這是一個大量的比較令人難以置信的緩慢和低效。存在是合理的大量項目的一個jQuery/js的方法 -

什麼是最快/最有效的方式做到這一點?或者是否需要重新構造Django代碼才能將其傳遞到模板?

回答

1

對於最可能的性能,使一個索引一次,然後再使用它:

function revealCite() { 
    var cites_index = $("#myText").data("cites_index"); 

    // if no cached index exists, prepare one (one-time hit code section) 
    if (!cites_index) { 
    var cites = $("#myNotes cite"); 
    var cites_count = cites.length(); 
    var cites_index = {}; 

    for (var i=0; i<cites_count; i++) { 
     var cite = cites[i], group = cites_index[cite.className]; 
     if (!group) cites_index[cite.className] = []; 
     group.push(cite); 
    } 
    $("#myText").data("cites_index", cites_index); 
    } 

    // use the index to work with related elements ("this" must be an <a> element) 
    $(cites_index[this.className]).show(); 
} 

現在觸發上述功能的任何方式你喜歡:

$("#myText a").each(revealCite); 

PS:你也可以做到這一點,在地方的for循環:

cites.each(function() { 
    var group = cites_index[this.className]; 
    if (!group) cites_index[this.className] = []; 
    group.push(this); 
}); 

但是它的代碼行數相同,可能會稍微慢一些。

1

怎麼是這樣的:

http://jsfiddle.net/9eXws/

$('#myText a').each(function() { 
    $("#myNotes ." + $(this).attr('class')).show(); 
});​ 

而不是做一個內每個,它只是追加當前a元素到選擇的類,並且在任何項目執行show()找到。

0

我認爲內部的find冗餘重新執行外部each的每個迭代。嘗試在循環開始之前將匹配的元素存儲在變量中。我還調整了您的解決方案通過DOM屬性得到的類名,而不是使用jQuery的attr

var $cites = $('#myNotes').find('cite'); 
$('#myText').find('a').each(function() { 
    var anchor = this; 
    $cites.each(function() { 
     if(this.className == anchor.className) { 
      $anchor.show(); 
    }); 
}); 
0

不是總是循環遍歷每個元素並比較每個元素,而應該使用Jquery的選擇器來爲你搜索。 這應該顯著加快工作:

$('#myText > a').each(function() { 
    var $anchor = $(this); 
    var anchor_class = $(this).attr('class'); 
    var elements = $('#myNotes > cite[class=' + anchor_class + ']'); 
    if (elements[0] != undefined) { 
     $anchor.show(); 
    } 
}); 
+0

多德...這就是我的回答,我給11小時以前只是一個詳細的重構,但有一個附加'如果()'聲明。 – user113716 2010-06-11 11:43:41