【问题标题】:Comparing two large sets of attributes比较两组大属性
【发布时间】:2010-06-10 19:23:21
【问题描述】:

假设你有一个 Django 视图,它有两个功能:

第一个函数使用 XSLT 样式表呈现一些 XML,并生成一个包含 1000 个子元素的 div,如下所示:

<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>

第二个函数使用另一个样式表呈现另一个 XML 文档以生成如下所示的 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 中的哪些元素具有与#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 代码来完成工作,然后再将其传递给模板?

【问题讨论】:

    标签: jquery python xml 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);
    });
    

    但它的代码行数相同,可能会慢一些。

    【讨论】:

      【解决方案2】:

      这样的事情怎么样:

      http://jsfiddle.net/9eXws/

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

      它不做内部每个,而是简单地将当前a 元素的类附加到选择器中,并对找到的任何项目执行show()

      【讨论】:

        【解决方案3】:

        我认为内部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();
            });
        });
        

        【讨论】:

          【解决方案4】:

          您应该使用 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();
              }
          });
          

          【讨论】:

          • 老兄...这只是对我 13 小时前给出的答案的详细重构,但添加了 if() 声明。
          猜你喜欢
          • 2014-03-22
          • 1970-01-01
          • 2015-03-19
          • 2010-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多