// 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>