// Sort an array of objects interdependent on one or more of // its key values. The initial array will not be mutated, // unless you re-assign it // // syntax // ------ // const sorted = XSort().create([arrOfObjects]) // .orderBy( // {key: [keyname], [descending=0/1] }, // {key: [keyname], [descending=0/1]} ); // Can use lambda methods for the keys that should be sorted // so if the value is an object, something like // [xsort].orderBy({key => key.firstName.startsWith("J")}, {[...]}, ...) ( d => { const booksArray = getData(); const booksSorted = XSort() .create(booksArray) .orderBy( { key: 'Rate' }, { key: 'Price', descending: 1 } ); d.querySelector("pre").textContent = JSON.stringify( booksSorted, null, " " ); function XSort() { const multiSorter = sortKeys => { if (!sortKeys || sortKeys[0].constructor !== Object) { throw new TypeError("Provide at least one {key: [keyname]} to sort on"); } return function (val0, val1) { for (let sortKey of sortKeys) { const v0 = sortKey.key instanceof Function ? sortKey.key(val0) : val0[sortKey.key]; const v1 = sortKey.key instanceof Function ? sortKey.key(val1) : val1[sortKey.key]; const isString = v0.constructor === String || v1.constructor === String; const compare = sortKey.descending ? isString ? v1.toLowerCase().localeCompare(v0.toLowerCase()) : v1 - v0 : isString ? v0.toLowerCase().localeCompare(v1.toLowerCase()) : v0 - v1; if ( compare !== 0 ) { return compare; } } }; } const Sorter = function (array) { this.array = array; }; Sorter.prototype = { orderBy: function(...sortOns) { return this.array.slice().sort(multiSorter(sortOns)); }, }; return { create: array => new Sorter(array) }; } function getData() { return [ {Rate:3, Id:16, Price:200, Name:"Functional Programming"}, {Rate:5, Id:1, Price:200, Name:"History"}, {Rate:5, Id:2, Price:150, Name:"Geographic"}, {Rate:2, Id:17, Price:190, Name:"Computer Science"}, {Rate:3, Id:15, Price:250, Name:"Jihad"}, {Rate:1, Id:3, Price:75, Name:"Maths"}, {Rate:3, Id:7, Price:110, Name:"Chemistry"}, {Rate:2, Id:4, Price:50, Name:"Statistics"}, {Rate:2, Id:6, Price:100, Name:"Arts"}, {Rate:4, Id:10, Price:80, Name:"Algorithm"}, {Rate:1, Id:11, Price:85, Name:"Urdu"}, {Rate:4, Id:8, Price:160, Name:"Biology"}, {Rate:1, Id:13, Price:120, Name:"Physics"}, {Rate:3, Id:14, Price:230, Name:"Electronics"}, {Rate:3, Id:5, Price:120, Name:"Drawing"}, {Rate:2, Id:18, Price:50, Name:"Problem solving Techniques"}, {Rate:6, Id:19, Price:150, Name:"C#"}, {Rate:7, Id:20, Price:250, Name:"ASP.Net"}, {Rate:1, Id:12, Price:110, Name:"International Relations"}, {Rate:4, Id:9, Price:90, Name:"Software Engineering"}, ]; } })(document);
<div class="solink" data-linkid="25157510"> <div class="linkhover">loading....</div> </div> <div id="result"> <code>data</code> ordered by Rate <i>and</i> Price descending (using <code>xSort.orderBy)</code> </div> <pre></pre>