代码之家  ›  专栏  ›  技术社区  ›  S16

用模数按字母顺序排列列表

  •  8
  • S16  · 技术社区  · 14 年前

    我在抓取元素列表并按字母顺序排序时没有任何问题,但我很难理解如何使用模数。

    ###更新###

    这里的代码工作'我的方式',然而,我喜欢的可重用性的答案下面提供了更多,所以我接受了这个答案。

    <script type="text/javascript">
    $(document).ready( function() {
        $('.sectionList2').each( function() {
            var oldList = $('li a', this),
                columns = 4,
                newList = [];
            for( var start = 0; start < columns; start++){
                for( var i = start; i < oldList.length; i += columns){
                    newList.push('<li><a href="' + oldList[i].href + '">' + $(oldList[i]).text() + '</a></li>');
                }
            }
            $(this).html(newList.join(''));
        });
    });
    </script>
    

    <ul>
        <li><a href="~">Boots</a></li>
        <li><a href="~">Eyewear</a></li>
        <li><a href="~">Gloves</a></li>
        <li><a href="~">Heated Gear</a></li>
        <li><a href="~">Helmet Accessories</a></li>
        <li><a href="~">Helmets</a></li>
        <li><a href="~">Jackets</a></li>
        <li><a href="~">Mechanic's Wear</a></li>
        <li><a href="~">Pants</a></li>
        <li><a href="~">Protection</a></li>
        <li><a href="~">Rainwear</a></li>
        <li><a href="~">Random Apparel</a></li>
        <li><a href="~">Riding Suits</a></li>
        <li><a href="~">Riding Underwear</a></li>
        <li><a href="~">Socks</a></li>
        <li><a href="~">Vests</a></li>
    </ul>
    

    我将这个列表设置为4列显示,每个li向右浮动。从视觉上看,这使得在较大的列表中查找项目变得困难。我需要的输出是:

    <ul>
        <li><a href="~">Boots</a></li>
        <li><a href="~">Helmet Accessories</a></li>
        <li><a href="~">Pants</a></li>
        <li><a href="~">Riding Suits</a></li>
        <li><a href="~">Eyewear</a></li>
        <li><a href="~">Helmets</a></li>
        <li><a href="~">Protection</a></li>
        <li><a href="~">Riding Underwear</a></li>
        <li><a href="~">Gloves</a></li>
        <li><a href="~">Jackets</a></li>
        <li><a href="~">Rainwear</a></li>
        <li><a href="~">Socks</a></li>
        <li><a href="~">Heated Gear</a></li>
        <li><a href="~">Mechanic's Wear</a></li>
        <li><a href="~">Random Apparel</a></li>
        <li><a href="~">Vests</a></li>
    </ul>
    

    我要找的是一个函数,我可以传递我的列表项数组,并返回我的数组,按字母顺序排序,选择一个模数;在本例中是4。

    4 回复  |  直到 14 年前
        1
  •  2
  •   gilly3    14 年前
    1. 按字母顺序排列你的名单。在您的情况下,这已经完成了,但如果没有:

      function alphabetizeElements(a, b)
      {
          var aText = $(a).text();
          var bText = $(b).text();
          return aText > bText ? 1 : aText < bText ? -1 : 0;
      }
      var alphabetizedList = $("#myList li").sort(alphabetizeElements);
      
    2. 存储每个元素的字母索引:

      $.each(alphabetizedList, function(i)
      {
          $(this).data("alphaIndex", i);
      });
      
    3. 先按模数对按字母顺序排列的列表排序,然后按索引排序:

      function listColumnSortFn(columns)
      {
          return function(a, b)
          {
              var aIndex = $(a).data("alphaIndex");
              var bIndex = $(b).data("alphaIndex");
              return ((aIndex % columns) - (bIndex % columns)) || (aIndex - bIndex);
          }
      }
      var columnSortedList = alphabetizedList.sort(listColumnSortFn(4));
      
    4. 用排序的元素替换列表元素:

      $("#myList li").remove();
      $("#myList").append(columnSortedList);
      

    这里是整个事情,全部加在一起:

    function sortList(columns)
    {
        var alphabetizedList = $("#myList li").sort(alphabetizeElements);
        $.each(alphabetizedList, function(i)
        {
            $(this).data("alphaIndex", i);
        });
        var columnSortedList = alphabetizedList.sort(listColumnSortFn(columns));
        $("#myList li").remove();
        $("#myList").append(columnSortedList);
    }
    function alphabetizeElements(a, b)
    {
        var aText = $(a).text();
        var bText = $(b).text();
        return aText > bText ? 1 : aText < bText ? -1 : 0;
    }
    function listColumnSortFn(columns)
    {
        return function(a, b)
        {
            var aIndex = $(a).data("alphaIndex");
            var bIndex = $(b).data("alphaIndex");
            return ((aIndex % columns) - (bIndex % columns)) || (aIndex - bIndex);
        }
    }
    $(function()
    {
        sortList(4);
    });
    
        2
  •  0
  •   Cristian Sanchez    14 年前
    var columnify = function (a,n) { 
        var result = []; 
        for (var i = 0, lastIndex = a.length - 1; i < lastIndex; i++) 
           result.push(a[i * n % (lastIndex)]); 
        result[lastIndex] = a[lastIndex];
        return result; 
    }
    
    var products = ["Boots",
    "Eyewear",
    "Gloves",
    "Heated Gear",
    "Helmet Accessories",
    "Helmets",
    "Jackets",
    "Mechanic's Wear",
    "Pants",
    "Protection",
    "Rainwear",
    "Random Apparel",
    "Riding Suits",
    "Riding Underwear",
    "Socks",
    "Vests",]
    
    columnify(products, 4)
    ["Boots", "Helmet Accessories", "Pants", "Riding Suits", "Eyewear", "Helmets", "Protection", "Riding Underwear", "Gloves", "Jackets", "Rainwear", "Socks", "Heated Gear", "Mechanic's Wear", "Random Apparel", "Vests"]
    

    将该函数应用于已排序的列表,然后它将按您想要的顺序(几乎)返回一个字符串列表。然后将按顺序返回的列表添加到DOM中的无序列表中。

    n . 不是一个很好的解决方案,但对我来说已经很晚了,我懒得想出更好的办法。

    编辑:修复了最后一个元素的问题

        3
  •  0
  •   Yi Jiang G-Man    14 年前

    看看这是否管用: http://jsfiddle.net/6xm9m/2

    var newList = new Array();
    var listItem = $('#list > li');
    var mod = 4;
    var colCount = Math.ceil(listItem.length / mod);
    
    listItem.each(function(index) {
        var newIndex = ((index % colCount) * mod) + Math.floor(index / colCount);
        // $(this).text(newIndex);
    
        newList[newIndex] = this;
    });
    
    $('#list').empty();
    
    for(var i = 0; i < newList.length; i++){
        $('#list').append(newList[i]);
    }
    

    可能需要改进,但我真的不确定这到底有多好。

        4
  •  0
  •   ErikE Russ Cam    14 年前

    function pivotArray(arr, columns) {
       var l = arr.length, out = [], ind = 0, i = 0;
       for (; i < l; i += 1) {
          out[ind] = arr[i];
          ind += columns;
          if (ind >= l) {
             ind = ind % columns + 1;
          }
       }
       return out;
    }
    

    下面的测试证明了它的有效性(在Firefox 3.6.9、IE 6、Chrome 1.0.154.36中进行了测试):

    <html>
    <head>
    <style type="text/css">
    a.panelnum {
       display:block;
       float:left;
       width:40px;
       height:40px;
       border:1px solid black;
       text-align:center;
       vertical-align:middle;
       text-decoration:none;
       font-size:2em;
    }
    </style>
    </head>
    <body onload="doit(17, 4);">
    <div id="output" style="border:1px solid blue;">
    </div>
    <script type="text/javascript">
    
    function pivotArray(arr, columns) {
       var l = arr.length, out = [], ind = 0, i = 0;
       for (; i < l; i += 1) {
          out[ind] = arr[i];
          ind += columns;
          if (ind >= l) {
             ind = ind % columns + 1;
          }
       }
       return out;
    }
    
    function doit(size, columns) {
       document.getElementById('output').innerHTML = 'starting';
       var l = size;
       var inp = [];
       for (var i = 0; i < l; i += 1) {
          inp[i] = i;   
       }
       var result = pivotArray(inp, columns);
       var str = '';
       for (i = 0; i < l; i += 1) {
          str += '<a class="panelnum">' + result[i] + '</a>';
       }
       var d = document.getElementById('output')
       d.innerHTML = '<p>Some pre text</p>' + str + '<p style="clear:both;">and some post text</p>';
       d.style.width = (columns * d.childNodes[1].offsetWidth + 2) + 'px';
    }
    </script>
    </body>
    </html>
    

    有人想给我指点一下为什么我要在IE6的宽度计算中加2吗?等待。。。这是部门的边界,不是吗?