SO Answer
Question: Resort array of objects on another key without disturbing previous sorting (part-sorting) in JavaScript #2.
by KooiInc MeHere
HTML
<script src="https://cdn.jsdelivr.net/gh/KooiInc/JSHelpers/Helpers.min.js"></script>
<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>
JavaScript
// 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"},
...