ti-enxame.com

Como posso classificar uma lista em ordem alfabética usando jQuery?

Estou um pouco fora da minha profundidade aqui e estou esperando que isso seja realmente possível.

Gostaria de poder chamar uma função que classificaria todos os itens da minha lista em ordem alfabética.

Eu tenho procurado através da interface do usuário do jQuery para classificação, mas isso não parece ser. Alguma ideia?

226
dougoftheabaci

Você não precisa do jQuery para fazer isso ...

function sortUnorderedList(ul, sortDescending) {
  if(typeof ul == "string")
    ul = document.getElementById(ul);

  // Idiot-proof, remove if you want
  if(!ul) {
    alert("The UL object is null!");
    return;
  }

  // Get the list items and setup an array for sorting
  var lis = ul.getElementsByTagName("LI");
  var vals = [];

  // Populate the array
  for(var i = 0, l = lis.length; i < l; i++)
    vals.Push(lis[i].innerHTML);

  // Sort it
  vals.sort();

  // Sometimes you gotta DESC
  if(sortDescending)
    vals.reverse();

  // Change the list on the page
  for(var i = 0, l = lis.length; i < l; i++)
    lis[i].innerHTML = vals[i];
}

Fácil de usar...

sortUnorderedList("ID_OF_LIST");

Demonstração ao vivo →

102
Josh Stodola

Algo assim:

var mylist = $('#myUL');
var listitems = mylist.children('li').get();
listitems.sort(function(a, b) {
   return $(a).text().toUpperCase().localeCompare($(b).text().toUpperCase());
})
$.each(listitems, function(idx, itm) { mylist.append(itm); });

A partir desta página: http://www.onemoretake.com/2009/02/25/sorting-elements-with-jquery/

O código acima classificará sua lista não ordenada com o id 'myUL'. 

OU você pode usar um plugin como o TinySort. https://github.com/Sjeiti/TinySort

318
SolutionYogi
$(".list li").sort(asc_sort).appendTo('.list');
//$("#debug").text("Output:");
// accending sort
function asc_sort(a, b){
    return ($(b).text()) < ($(a).text()) ? 1 : -1;    
}

// decending sort
function dec_sort(a, b){
    return ($(b).text()) > ($(a).text()) ? 1 : -1;    
}

demonstração ao vivo: http://jsbin.com/eculis/876/edit

85
Jeetendra Chauhan

Para fazer este trabalho funcionar com todos os navegadores, incluindo o Chrome, você precisa fazer a função de retorno de chamada de sort () return -1,0 ou 1. 

veja http://inderpreetsingh.com/2010/12/01/chromes-javascript-sort-array-function-is-different-yet-proper/

function sortUL(selector) {
    $(selector).children("li").sort(function(a, b) {
        var upA = $(a).text().toUpperCase();
        var upB = $(b).text().toUpperCase();
        return (upA < upB) ? -1 : (upA > upB) ? 1 : 0;
    }).appendTo(selector);
}
sortUL("ul.mylist");
39
PatrickHeck

Se você estiver usando o jQuery, você pode fazer isso:

$(function() {

  var $list = $("#list");

  $list.children().detach().sort(function(a, b) {
    return $(a).text().localeCompare($(b).text());
  }).appendTo($list);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<ul id="list">
  <li>delta</li>
  <li>cat</li>
  <li>alpha</li>
  <li>cat</li>
  <li>beta</li>
  <li>gamma</li>
  <li>gamma</li>
  <li>alpha</li>
  <li>cat</li>
  <li>delta</li>
  <li>bat</li>
  <li>cat</li>
</ul>

Note que retornar 1 e -1 (ou 0 e 1) da função de comparação está absolutamente errado .

27
Salman A

A resposta do @ SolutionYogi funciona como um encanto, mas parece que usar $ .each é menos direto e eficiente do que listitems diretamente anexados:

var mylist = $('#list');
var listitems = mylist.children('li').get();

listitems.sort(function(a, b) {
   return $(a).text().toUpperCase().localeCompare($(b).text().toUpperCase());
})

mylist.empty().append(listitems);

Fiddle

6
Buzut

Eu estava olhando para fazer isso sozinho, e eu não estava satisfeito com qualquer das respostas fornecidas simplesmente porque, creio eu, eles são tempo quadrático, e eu preciso fazer isso na lista de centenas de itens de comprimento.

Eu acabei estendendo jquery, e minha solução usa jquery, mas poderia ser facilmente modificado para usar javascript direto.

Eu só acesso cada item duas vezes, e faço uma classificação linear, então, acho que isso deve ser muito mais rápido em grandes conjuntos de dados, embora eu confesse livremente que posso estar enganado:

sortList: function() {
   if (!this.is("ul") || !this.length)
      return
   else {
      var getData = function(ul) {
         var lis     = ul.find('li'),
             liData  = {
               liTexts : []
            }; 

         for(var i = 0; i<lis.length; i++){
             var key              = $(lis[i]).text().trim().toLowerCase().replace(/\s/g, ""),
             attrs                = lis[i].attributes;
             liData[key]          = {},
             liData[key]['attrs'] = {},
             liData[key]['html']  = $(lis[i]).html();

             liData.liTexts.Push(key);

             for (var j = 0; j < attrs.length; j++) {
                liData[key]['attrs'][attrs[j].nodeName] = attrs[j].nodeValue;
             }
          }

          return liData;
       },

       processData = function (obj){
          var sortedTexts = obj.liTexts.sort(),
              htmlStr     = '';

          for(var i = 0; i < sortedTexts.length; i++){
             var attrsStr   = '',
                 attributes = obj[sortedTexts[i]].attrs;

             for(attr in attributes){
                var str = attr + "=\'" + attributes[attr] + "\' ";
                attrsStr += str;
             }

             htmlStr += "<li "+ attrsStr + ">" + obj[sortedTexts[i]].html+"</li>";
          }

          return htmlStr;

       };

       this.html(processData(getData(this)));
    }
}
0
Quirkles

Coloque a lista em uma matriz, use .sort() do JavaScript, que por padrão é alfabético, e converta a matriz de volta para uma lista.

http://www.w3schools.com/jsref/jsref_sort.asp

0
Elon Zito

HTML

<ul id="list">
    <li>alpha</li>
    <li>gamma</li>
    <li>beta</li>
</ul>

JavaScript

function sort(ul) {
    var ul = document.getElementById(ul)
    var liArr = ul.children
    var arr = new Array()
    for (var i = 0; i < liArr.length; i++) {
        arr.Push(liArr[i].textContent)
    }
    arr.sort()
    arr.forEach(function(content, index) {
        liArr[index].textContent = content
    })
}

sort("list")

Demonstração JSFiddle https://jsfiddle.net/97oo61nw/

Aqui nós enviamos todos os valores dos elementos li dentro de ul com id específica (que fornecemos como argumento de função) para array arr e classificá-lo usando o método sort () que é classificado alfabeticamente por padrão. Depois que a matriz arr é classificada, fazemos loop dessa matriz usando o método forEach () e apenas substituímos o conteúdo de texto de todos os elementos li pelo conteúdo classificado.

0
Mikhail