Skip to content

Instantly share code, notes, and snippets.

@rmkane
Last active October 8, 2015 23:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmkane/d344314e7e45d26f3522 to your computer and use it in GitHub Desktop.
Save rmkane/d344314e7e45d26f3522 to your computer and use it in GitHub Desktop.
Dynamic Multi-Sort

A sorting helper to sort an array of objects using multiple sorting properties. Property scoping is supported.

Your sorters can be simple property strings, or sorter objects.

This gist can be viewed at bl.ocks.org. Alternatively, you can view this example over at JSFiddle.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css" />
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="sorter.js"></script>
<script type="text/javascript">
function toJson(obj, indent) {
return JSON.stringify(obj, null, indent || 1);
}
$.getJSON('people.json', function(people) {
var sortedPeople1 = people.sortBy('person.name.first', '-person.name.last');
$('#col1').html(toJson(sortedPeople1));
var sortedPeople2 = people.sortBy({
property: 'person.name.first',
direction: 'ASC'
}, {
property: 'person.name.last',
direction: 'DESC'
});
$('#col2').html(toJson(sortedPeople2));
});;
</script>
</head>
<body>
<div class="section group">
<div class="col span_1_of_2" id="col1"></div>
<div class="col span_1_of_2" id="col2"></div>
</div>
</body>
</html>
[{
"person": {
"name": {
"first": "Patrick",
"last": "Swayze"
}
}
}, {
"person": {
"name": {
"first": "Ian",
"last": "Anderson"
}
}
}, {
"person": {
"name": {
"first": "Wil",
"last": "Wheaton"
}
}
}, {
"person": {
"name": {
"first": "Patrick",
"last": "Stewart"
}
}
}, {
"person": {
"name": {
"first": "Ian",
"last": "McKellen"
}
}
}]
Object.defineProperty(Object.prototype, 'deepVal', {
enumerable: false,
writable: true,
value: function (propertyChain) {
var levels = propertyChain.split('.');
var parent = this;
for (var i = 0; i < levels.length; i++) {
if (!parent[levels[i]]) return undefined;
parent = parent[levels[i]];
}
return parent;
}
});
function _dynamicSort(sorter) {
var property = sorter;
var direction = 1;
if (typeof sorter !== 'string') {
property = sorter.property;
direction = sorter.direction === 'DESC' ? -1 : 1;
} else {
if (property[0] === '-') {
direction = -1;
property = property.substr(1);
}
}
return function (a, b) {
var aVal = a.deepVal(property);
var bVal = b.deepVal(property);
if (aVal < bVal) {
return -1 * direction;
} else if (aVal > bVal) {
return 1 * direction;
} else {
return 0;
}
}
}
function _dynamicSorter(sorters) {
var properties = arguments;
return function (obj1, obj2) {
var index = 0,
result = 0;
while (result === 0 && index < properties.length) {
result = _dynamicSort(properties[index++]).apply(null, arguments);
}
return result;
};
}
Object.defineProperty(Array.prototype, 'sortBy', {
enumerable: false,
writable: true,
value: function () {
return this.sort(_dynamicSorter.apply(null, arguments));
}
});
body {
font-family: monospace;
background: #444;
overflow: hidden;
}
/**
* Generated via http://www.responsivegridsystem.com/calculator/
*/
/* SECTIONS */
.section {
clear: both;
padding: 0px;
margin: 0px 1%;
height: 480px;
}
/* COLUMN SETUP */
.col {
display: block;
float: left;
margin: 1% 0 1% 1.6%;
padding: 2%;
background: #FFF;
white-space: pre;
overflow: auto;
height: 92%;
}
.col:first-child {
margin-left: 0;
}
/* GROUPING */
.group:before, .group:after {
content: "";
display: table;
}
.group:after {
clear: both;
}
.group {
zoom: 1; /* For IE 6/7 */
}
/* GRID OF TWO */
.span_2_of_2 {
width: 100%;
}
.span_1_of_2 {
width: 45.2%;
}
/* GO FULL WIDTH AT LESS THAN 480 PIXELS */
@media only screen and (max-width: 480px) {
.col {
margin: 1% 0 1% 0%;
}
}
@media only screen and (max-width: 480px) {
.span_2_of_2, .span_1_of_2 {
width: 96%;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment