0

My sort function doesn't work if one of the attribute has no value: E.G:

JS:

function sortEventsByOrder(a,b) {
        const startA = parseInt($(a).data('order'));
        const startB = parseInt($(b).data('order'));    
        return startA - startB;
    }
    $('#eventList').html($('#eventList li').sort(sortEventsByOrder))

HTML:

<html>
  <head>
    <link rel="stylesheet" href="lib/style.css">
    <script src="lib/script.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  </head>

  <body>


<ul id="eventList">
   <li data-order="5">Element 5</li>
   <li data-order="">Element 3</li>
   <li data-order="6">Element 6</li>
   <li data-order="1">Element 1</li>
   <li data-order="2">Element 2</li>
   <li data-order="4">Element 4</li>
</ul>
  </body>
</html>

enter image description here As you can see from screen shoot only sort from 6.

How can I sort the empty values to the bottom? or how to get around this issue?

Thanks.

Juliano
  • 141
  • 1
  • 11

2 Answers2

2

Set the blank data points to use max value

function sortEventsByOrder(a, b) {
  const startA = parseInt($(a).data('order')) || Number.MAX_VALUE;
  const startB = parseInt($(b).data('order')) || Number.MAX_VALUE;
  return startA === startB ? 0 : startA > startB ? 1 : -1;
}

$('#eventList').append($('#eventList li').sort(sortEventsByOrder))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="eventList">
  <li data-order="5"> Element 5
  </li>
  <li data-order=""> Element 3
  </li>
  <li data-order="6"> Element 6
  </li>
  <li data-order="1"> Element 1
  </li>
  <li data-order="2"> Element 2
  </li>
  <li data-order="4"> Element 4
  </li>
</ul>

numbers with decimals

function sortEventsByOrder(a, b) {
  var orderA = $(a).data('order')
  var orderB = $(b).data('order')
  const startA = orderA === "" ? Number.MAX_VALUE: +orderA;
  const startB = orderB === "" ? Number.MAX_VALUE: +orderB;
  return startA === startB ? 0 : startA > startB ? 1 : -1;
}

$('#eventList').append($('#eventList li').sort(sortEventsByOrder))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="eventList">
  <li data-order="5"> Element 5
  </li>
  <li data-order=""> Element 3
  </li>
  <li data-order="6"> Element 6
  </li>
  <li data-order="0"> Element 1
  </li>
  <li data-order="2.2"> Element 2
  </li>
  <li data-order="2.3"> Element 4
  </li>
</ul>
epascarello
  • 204,599
  • 20
  • 195
  • 236
  • Good solution it also works I was also missing parseInt which in my case I was using with dynamic distance and float point which in case of 100.0 and 50.0 it would not sort as expected thanks for the suggestion. – Juliano Feb 07 '20 at 10:38
  • I have used you solution it worked until the introduction of float pointing number however it fixed by changing to `parseFloat` but there is yet another introduction which is `0.0` it doesn't work, What could I try ? call another function in the end to move element at the top any suggestion thks – Juliano Feb 24 '20 at 15:02
  • well 0 would be considered a falsely value so you would need to use https://www.w3schools.com/jsref/jsref_isNaN.asp – epascarello Feb 24 '20 at 15:08
  • Awesome! Super Thnks – Juliano Feb 24 '20 at 15:32
  • sort from highest to the lowest, any solution? – Karue Benson Karue Nov 30 '21 at 23:53
  • @KarueBensonKarue swap the -1 and 1?? – epascarello Dec 01 '21 at 00:40
  • I surprisingly changed `startA > startB ? 1 : -1;` to `startA < startB ? 1 : -1;` and it worked great. I just changed `>` to `<`. I cannot really explain how it worked but worked and sorted from largest order to the smallest, which was what I was looking for – Karue Benson Karue Dec 01 '21 at 03:12
  • because you flipped the order.... – epascarello Dec 01 '21 at 04:03
1

found my answer Sort an array so that null values always come last:

function alphabetically(ascending) {

return function (a, b) {

// equal items sort equally
if (a === b) {
    return 0;
}
// nulls sort after anything else
else if (a === null) {
    return 1;
}
else if (b === null) {
    return -1;
}
// otherwise, if we're ascending, lowest sorts first
else if (ascending) {
    return a < b ? -1 : 1;
}
// if descending, highest sorts first
else { 
    return a < b ? 1 : -1;
}

};

}

 var arr = [null, 'a', 'b', null, 'd'];

 console.log(arr.sort(alphabetically(true)));
 console.log(arr.sort(alphabetically(false)));

The above works for me it can be applied in DOM elements in case!

Juliano
  • 141
  • 1
  • 11