【问题标题】:Sorting a list alphabetically with a modulus使用模数按字母顺序对列表进行排序
【发布时间】:2011-04-10 13:22:11
【问题描述】:

获取元素列表并按字母顺序对它们进行排序没有任何问题,但我很难理解如何使用模数。

### 更新###

这是“我的方式”工作的代码,但是,我更喜欢下面提供的答案的可重用性,因此接受了该答案。

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

任何帮助将不胜感激,因为我找不到有关该主题的文档。

【问题讨论】:

  • 你能发布你已经拥有的代码吗?
  • 而且,假设您是从后端开发的,为什么不在服务器端执行此操作?
  • 其实有一个 CSS 解决方案,column-count
  • 后端解决方案是理想的,但在这种情况下是不可能的。到目前为止,我所拥有的东西正在爆炸,这不是一个很好的起点。

标签: javascript jquery sorting modulus


【解决方案1】:
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 的倍数时才有效。不是一个很好的解决方案,但对我来说已经晚了,我懒得想出更好的办法了。

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

【讨论】:

  • 理论相当合理,但实现不正确。传入一个 n = 4 的 17 元素数组会产生 0 4 8 12 四次,最后在第五行产生 16。
  • @Emtucidifor:是的。就像我说的,当 n%lenght != 0 时它不起作用。
【解决方案2】:

看看这是否可行: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]);
}

可能需要改进,但我不确定它的效果如何。

【讨论】:

    【解决方案3】:

    给你。一旦你弄清楚了,代码就非常简单。我意识到您正在使用 jQuery,但我对它还不够熟悉,无法使用它的功能。这很简单,也许没有必要。

    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>
    

    还有一件事:只在原地移动元素可能会很有用。我几乎有了它的脚本,但我的脚本倒退了(好像花车先从上到下)。如果我有时间,我会处理它并发布代码。

    附:任何人都想告诉我为什么我必须将 2 添加到 IE6 的宽度计算中?等等...不是 div 的边框吗?

    【讨论】:

      【解决方案4】:
      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);
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-02
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多