Sorting JSON by values

JqueryJson

Jquery Problem Overview


I have a very simple JSON object like the following:

{
   "people":[
      {
         "f_name":"john",
         "l_name":"doe",
         "sequence":"0",
         "title":"president",
         "url":"google.com",
         "color":"333333"
      },
      {
         "f_name":"michael",
         "l_name":"goodyear",
         "sequence":"0",
         "title":"general manager",
         "url":"google.com",
         "color":"333333"
      }
   ]
}

Now that this is returned from my server side code, I run jQuery.each to form the necessary html and output the result.

Right now what I am doing is sending an AJAX call to the server containing my sort info... e.g. "Title DESC" and re-run an SQL query to return the new result set. But I want to avoid this and use jQuery to sort the resulting JSON to prevent round trips to the server, and multiple database access.

How can I achieve this using jQuery?

Jquery Solutions


Solution 1 - Jquery

jQuery isn't particularly helpful for sorting, but here's an elegant and efficient solution. Just write a plain JS function that takes the property name and the order (ascending or descending) and calls the native sort() method with a simple comparison function:

var people = [
    {
        "f_name": "john",
        "l_name": "doe",
        "sequence": "0",
        "title" : "president",
        "url" : "google.com",
        "color" : "333333",
    }
    // etc
];

function sortResults(prop, asc) {
    people.sort(function(a, b) {
        if (asc) {
            return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
        } else {
            return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
        }
    });
    renderResults();
}

Then:

sortResults('l_name', true);

Play with a working example here.

Solution 2 - Jquery

Demo: https://jsfiddle.net/kvxazhso/

Successfully pass equal values (keep same order). Flexible : handle ascendant (123) or descendant (321), works for numbers, letters, and unicodes. Works on all tested devices (Chrome, Android default browser, FF).

Given data such :

var people = [ 
{ 'myKey': 'A', 'status': 0 },
{ 'myKey': 'B', 'status': 3 },
{ 'myKey': 'C', 'status': 3 },
{ 'myKey': 'D', 'status': 2 },
{ 'myKey': 'E', 'status': 7 },
...
];

Sorting by ascending or reverse order:

function sortJSON(arr, key, way) {
    return arr.sort(function(a, b) {
        var x = a[key]; var y = b[key];
        if (way === '123') { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }
        if (way === '321') { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); }
    });
}

people2 = sortJSON(people,'status', '321'); // 123 or 321
alert("2. After processing (0 to x if 123; x to 0 if 321): "+JSON.stringify(people2));

Solution 3 - Jquery

jQuery.fn.sort = function() {  
    return this.pushStack( [].sort.apply( this, arguments ), []);  
};  
   
 function sortLastName(a,b){  
     if (a.l_name == b.l_name){
       return 0;
     }
     return a.l_name> b.l_name ? 1 : -1;  
 };  
  function sortLastNameDesc(a,b){  
     return sortLastName(a,b) * -1;  
 };
var people= [
{
"f_name": "john",
"l_name": "doe",
"sequence": "0",
"title" : "president",
"url" : "google.com",
"color" : "333333",
},
{
"f_name": "michael",
"l_name": "goodyear",
"sequence": "0",
"title" : "general manager",
"url" : "google.com",
"color" : "333333",
}]

sorted=$(people).sort(sortLastNameDesc);  

Solution 4 - Jquery

If you don't mind using an external library, Lodash has lots of wonderful utilities

var people = [
  {
     "f_name":"john",
     "l_name":"doe",
     "sequence":"0",
     "title":"president",
     "url":"google.com",
     "color":"333333"
  },
  {
     "f_name":"michael",
     "l_name":"goodyear",
     "sequence":"0",
     "title":"general manager",
     "url":"google.com",
     "color":"333333"
  }
];


var sorted = _.sortBy(people, "l_name")

You can also sort by multiple properties. Here's a plunk showing it in action

Solution 5 - Jquery

Solution working with different types and with upper and lower cases.
For example, without the toLowerCase statement, "Goodyear" will come before "doe" with an ascending sort. Run the code snippet at the bottom of my answer to view the different behaviors.

JSON DATA:

var people = [
{
    "f_name" : "john",
    "l_name" : "doe", // lower case
    "sequence": 0 // int
},
{
    "f_name" : "michael",
    "l_name" : "Goodyear", // upper case
    "sequence" : 1 // int
}];

JSON Sort Function:

function sortJson(element, prop, propType, asc) {
  switch (propType) {
    case "int":
	  element = element.sort(function (a, b) {
	    if (asc) {
		  return (parseInt(a[prop]) > parseInt(b[prop])) ? 1 : ((parseInt(a[prop]) < parseInt(b[prop])) ? -1 : 0);
		} else {
		  return (parseInt(b[prop]) > parseInt(a[prop])) ? 1 : ((parseInt(b[prop]) < parseInt(a[prop])) ? -1 : 0);
		}
	  });
	  break;
	default:
	  element = element.sort(function (a, b) {
	    if (asc) {
		  return (a[prop].toLowerCase() > b[prop].toLowerCase()) ? 1 : ((a[prop].toLowerCase() < b[prop].toLowerCase()) ? -1 : 0);
		} else {
		  return (b[prop].toLowerCase() > a[prop].toLowerCase()) ? 1 : ((b[prop].toLowerCase() < a[prop].toLowerCase()) ? -1 : 0);
		}
	  });
  }
}

Usage:

sortJson(people , "l_name", "string", true);
sortJson(people , "sequence", "int", true);

var people = [{
  "f_name": "john",
  "l_name": "doe",
  "sequence": 0
}, {
  "f_name": "michael",
  "l_name": "Goodyear",
  "sequence": 1
}, {
  "f_name": "bill",
  "l_name": "Johnson",
  "sequence": 4
}, {
  "f_name": "will",
  "l_name": "malone",
  "sequence": 2
}, {
  "f_name": "tim",
  "l_name": "Allen",
  "sequence": 3
}];

function sortJsonLcase(element, prop, asc) {
  element = element.sort(function(a, b) {
    if (asc) {
      return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
    } else {
      return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
    }
  });
}

function sortJson(element, prop, propType, asc) {
  switch (propType) {
    case "int":
      element = element.sort(function(a, b) {
        if (asc) {
          return (parseInt(a[prop]) > parseInt(b[prop])) ? 1 : ((parseInt(a[prop]) < parseInt(b[prop])) ? -1 : 0);
        } else {
          return (parseInt(b[prop]) > parseInt(a[prop])) ? 1 : ((parseInt(b[prop]) < parseInt(a[prop])) ? -1 : 0);
        }
      });
      break;
    default:
      element = element.sort(function(a, b) {
        if (asc) {
          return (a[prop].toLowerCase() > b[prop].toLowerCase()) ? 1 : ((a[prop].toLowerCase() < b[prop].toLowerCase()) ? -1 : 0);
        } else {
          return (b[prop].toLowerCase() > a[prop].toLowerCase()) ? 1 : ((b[prop].toLowerCase() < a[prop].toLowerCase()) ? -1 : 0);
        }
      });
  }
}

function sortJsonString() {
  sortJson(people, 'l_name', 'string', $("#chkAscString").prop("checked"));
  display();
}

function sortJsonInt() {
  sortJson(people, 'sequence', 'int', $("#chkAscInt").prop("checked"));
  display();
}

function sortJsonUL() {
  sortJsonLcase(people, 'l_name', $('#chkAsc').prop('checked'));
  display();
}

function display() {
  $("#data").empty();
  $(people).each(function() {
    $("#data").append("<div class='people'>" + this.l_name + "</div><div class='people'>" + this.f_name + "</div><div class='people'>" + this.sequence + "</div><br />");
  });
}

body {
  font-family: Arial;
}
.people {
  display: inline-block;
  width: 100px;
  border: 1px dotted black;
  padding: 5px;
  margin: 5px;
}
.buttons {
  border: 1px solid black;
  padding: 5px;
  margin: 5px;
  float: left;
  width: 20%;
}
ul {
  margin: 5px 0px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons" style="background-color: rgba(240, 255, 189, 1);">
  Sort the JSON array <strong style="color: red;">with</strong> toLowerCase:
  <ul>
    <li>Type: string</li>
    <li>Property: lastname</li>
  </ul>
  <button onclick="sortJsonString(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAscString" type="checkbox" checked="checked" />
</div>
<div class="buttons" style="background-color: rgba(255, 214, 215, 1);">
  Sort the JSON array <strong style="color: red;">without</strong> toLowerCase:
  <ul>
    <li>Type: string</li>
    <li>Property: lastname</li>
  </ul>
  <button onclick="sortJsonUL(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAsc" type="checkbox" checked="checked" />
</div>
<div class="buttons" style="background-color: rgba(240, 255, 189, 1);">
  Sort the JSON array:
  <ul>
    <li>Type: int</li>
    <li>Property: sequence</li>
  </ul>
  <button onclick="sortJsonInt(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAscInt" type="checkbox" checked="checked" />
</div>
<br />
<br />
<div id="data" style="float: left; border: 1px solid black; width: 60%; margin: 5px;">Data</div>

Solution 6 - Jquery

Here's a multiple-level sort method. I'm including a snippet from an Angular JS module, but you can accomplish the same thing by scoping the sort keys objects such that your sort function has access to them. You can see the full module at Plunker.

$scope.sortMyData = function (a, b)
{
  var retVal = 0, key;
  for (var i = 0; i < $scope.sortKeys.length; i++)
  {
    if (retVal !== 0)
    {
      break;
    }
    else
    {
      key = $scope.sortKeys[i];
      if ('asc' === key.direction)
      {
        retVal = (a[key.field] < b[key.field]) ? -1 : (a[key.field] > b[key.field]) ? 1 : 0;
      }
      else
      {
        retVal = (a[key.field] < b[key.field]) ? 1 : (a[key.field] > b[key.field]) ? -1 : 0;
      }
    }
  }
  return retVal;
};

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSubliminal HashView Question on Stackoverflow
Solution 1 - JquerySean the BeanView Answer on Stackoverflow
Solution 2 - JqueryHugolpzView Answer on Stackoverflow
Solution 3 - JqueryTahir AkhtarView Answer on Stackoverflow
Solution 4 - JquerytcqlView Answer on Stackoverflow
Solution 5 - JquerykrlzlxView Answer on Stackoverflow
Solution 6 - JqueryKSevView Answer on Stackoverflow