user1372212
user1372212

Reputation: 393

Javascript secondary sort

I have a list of ingredients that makeup part of a formulation as per below (hypothetical values)

<ul class="ing-list">
 <li value="Water" percent ="80" name="Water">Water - 80%</li>
 <li value="Whiskey" percent ="8" name="Water">Whiskey - 8%</li>
 <li value="Beer" percent ="4" name="Beer">Beer - 4%</li>
 <li value="Vodka" percent ="4" name="Vodka">Vodka - 4%</li>
 <li value="Orange" percent ="4" name="Orange">Orange - 4%</li>
</ul>

Everytime i add a new item to this list i run the following function to sort it by percentage value.

function sortList(){
    var list = $('.ing-list');
    var listItems = list.find('li').sort(function(b,a){ return $(a).attr('percent') - $(b).attr('percent'); });
    list.find('li').remove();
    list.append(listItems);
}

While this works fine for the function I also need to secondary sort the list alphabetically if the percentages are equal (can go into decimal).

I've not been able to find a solution that does not utilise a plugin which I wish to avoid at this time.

Any suggestions would be greatly appreciated.

Upvotes: 0

Views: 973

Answers (2)

Jeremias Nater
Jeremias Nater

Reputation: 803

Clean & Easy Solution

As no one has mentioned it yet: Javascript maintains the order for same values while sorting. This means you can chain sorts like this:

users
  .sort((a, b) => {
    return b.matchPercentage - a.matchPercentage;
  })
  .sort((a, b) => {
    return b.status - a.status;
  });

This will cause 2 loops instead of just one, but keeps the code simple. As sorts are efficient ( O(n) ) this is not an issue in 99% of cases.

Upvotes: 0

DThought
DThought

Reputation: 1314

You'll need to change the comperator that you defined, like:

function(b, a) { 
  var result = $(a).attr('percent') - $(b).attr('percent');

  if (result !== 0) {  
    return result;
  }

  //Do secondary sort decision here:
  if ($(a).attr('name') < $(b).attr('name')) {
    return 1;
  } 

  if ($(a).attr('name') > $(b).attr('name')) {
    return -1;
  }

  return 0;
}

Upvotes: 4

Related Questions