Srain Chen
Srain Chen

Reputation: 28

Why Array sort function returns the changed result in Javascript?

When I used the Array sort function to sort a <ul> list, I got a strange result.

The code is here:

<style>
    ul, li{
      display:block;
      font-size:10px!important;
      white-space:nowrap!important;
    }
    ul{
      clear:both;
      overflow: hidden;
    }
    li{
      float: left;
      width: 80px;
      margin: 2px;
      overflow: hidden;
    }
    .sourceList{
      background: skyblue;
    }
    .changeList{
      background: pink;
    }
</style>

<ul class="sourceList">
  <li><span>87761</span></li>
  <li><span>87762</span></li>
  <li><span>87763</span></li>
  <li><span>87764</span></li>
  <li><span>87765</span></li>
  <li><span>87766</span></li>
  <li><span>87767</span></li>
  <li><span>87768</span></li>
  <li><span>87769</span></li>
  <li><span>877610</span></li>
  <li><span>877611</span></li>
  <li><span>877612</span></li>
  <li><span>877613</span></li>
  <li><span>877614</span></li>
</ul>

<ul class="changeList">
  <li><span>87761</span></li>
  <li><span>87762</span></li>
  <li><span>87763</span></li>
  <li><span>87764</span></li>
  <li><span>87765</span></li>
  <li><span>87766</span></li>
  <li><span>87767</span></li>
  <li><span>87768</span></li>
  <li><span>87769</span></li>
  <li><span>877610</span></li>
  <li><span>877611</span></li>
  <li><span>877612</span></li>
  <li><span>877613</span></li>
  <li><span>877614</span></li>
</ul>

<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
    var t1 = $('.changeList li')
    t1.sort(function(a,b){
        return 0;
    });
    $('.changeList').html(t1);
</script>

I created two <ul> and them included same content. After I used the sort function in the children of the second <ul>, I found the result has been changed even though I input an empty function parameter.

enter image description here

Why it is so?

Upvotes: 1

Views: 79

Answers (3)

Shishir Kushwaha
Shishir Kushwaha

Reputation: 163

Contiguous arrays of non-numeric type are stringified and sorted using mergesort, if available (to obtain a stable sorting) or qsort if no merge sort is available.

Now all the elements of t1 when stringified internally by sort() gives "[object HTMLLIElement]". This is because your jQuery selector selects the DOM, not their value.

Hence, undesired result.

Try running this and you will get your answer.

var t1 = $('.changeList li');
var t2 = [];
for (i = 0; i < t1.length; i++) { 
    t2.push(t1[i].toString()); //this is what happens in sort() before initiating merger sort.
}
console.log(t2);

Upvotes: 0

Charu Rajput
Charu Rajput

Reputation: 653

<style>
    ul, li{
      display:block;
      font-size:10px!important;
      white-space:nowrap!important;
    }
    ul{
      clear:both;
      overflow: hidden;
    }
    li{
      float: left;
      width: 80px;
      margin: 2px;
      overflow: hidden;
    }
    .sourceList{
      background: skyblue;
    }
    .changeList{
      background: pink;
    }
</style>

<ul class="sourceList">
  <li><span>87761</span></li>
  <li><span>87762</span></li>
  <li><span>87763</span></li>
  <li><span>87764</span></li>
  <li><span>87765</span></li>
  <li><span>87766</span></li>
  <li><span>87767</span></li>
  <li><span>87768</span></li>
  <li><span>87769</span></li>
  <li><span>877610</span></li>
  <li><span>877611</span></li>
  <li><span>877612</span></li>
  <li><span>877613</span></li>
  <li><span>877614</span></li>
</ul>

<ul class="changeList">
  <li><span>87761</span></li>
  <li><span>87762</span></li>
  <li><span>87750</span></li>
  <li><span>87764</span></li>
  <li><span>87765</span></li>
  <li><span>87707</span></li>
  <li><span>87767</span></li>
  <li><span>87768</span></li>
  <li><span>87769</span></li>
  <li><span>877610</span></li>
  <li><span>877611</span></li>
  <li><span>877612</span></li>
  <li><span>877614</span></li>
  <li><span>877613</span></li>
</ul>

<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
     $('.changeList').children().detach().sort(function(a, b) {
    return $(a).text() - ($(b).text());
  }).appendTo('.changeList');
</script>

For sorting a list use following    

<script>
         $('.changeList').children().detach().sort(function(a, b) {
        return $(a).text() - ($(b).text());
      }).appendTo('.changeList');
    </script>

Upvotes: 1

Aleksey Shein
Aleksey Shein

Reputation: 7482

Returning zero as a result from sorting functions means that elements are equal to each other. As you don't know the underlying sorting algorithm, elements can be fed to your function in any order, only result matters.

And since your function says that all elements are equal, they can come out in any result (in fact, in the order that is most suitable for underlying sorting algorithm).

Upvotes: 1

Related Questions