Skip to content

Instantly share code, notes, and snippets.

@Jezternz
Created January 25, 2019 08:25
Show Gist options
  • Save Jezternz/45a070531279d8d0cb0d632b811f9932 to your computer and use it in GitHub Desktop.
Save Jezternz/45a070531279d8d0cb0d632b811f9932 to your computer and use it in GitHub Desktop.
(() =>
{
const list = [
{ a: "A", b: "2", c: 2, d: "2019-01-25T23:27:50.859Z", z: false },
{ a: "c", b: "4", c: 4, d: "2019-01-27T23:27:50.859Z", z: true },
{ a: "aa", b: "13", c: 11, d: "2019-01-28T23:27:50.859Z", z: false },
{ a: "aa", b: "11", c: 11, d: "2019-01-29T23:27:50.859Z", z: true },
{ a: "aa", b: "11", c: 11, d: "2019-02-29T23:27:50.859Z", z: false },
{ a: "aa", b: "11", c: 11, d: "2019-01-28T23:27:50.859Z", z: false },
{ a: "aa", b: "12", c: 11, d: "2019-01-28T23:27:50.859Z", z: false },
{ a: undefined, b: undefined, c: undefined, d: undefined, z: true },
{ a: null, b: null, c: null, d: null, z: false },
{ a: false, b: false, c: false, d: false, z: true },
{ a: true, b: true, c: true, d: true, z: false },
{ a: "", b: "", c: "", d: "", z: true },
{ },
{ a: "a", b: "1", c: 1, d: "2019-01-24T23:27:50.859Z", z: false },
{ a: "b", b: "3", c: 3, d: "2019-01-26T23:27:50.859Z", z: true },
]
const negativeVal = Math.floor(Number.MIN_SAFE_INTEGER/2);
const asComparable = t =>
{
if(t === undefined)return negativeVal;
if(t === null)return negativeVal+1;
t = t+"";
if(t === "")return negativeVal+2;
if(t === "false")return negativeVal+3;
if(t === "true")return negativeVal+4;
if(t.search(/^\d+(\.\d+)?$/gi) !== -1)return parseFloat(t);
const d = new Date(t);
if(!isNaN(d))return d.getTime();
return t;
};
const compareValues = ([{ field, dir }, ...moreSortOpts],a, b) =>
{
const fieldA = asComparable(a[field]), fieldB = asComparable(b[field]);
const diff = (
(typeof fieldA === "string" || typeof fieldB === "string") ?
(typeof fieldA === "string" ? fieldA : "").localeCompare(typeof fieldB === "string" ? fieldB : "") * -dir:
(fieldB - fieldA) * dir);
return diff !== 0 ? diff : moreSortOpts.length ? compareValues(moreSortOpts, a, b) : 0;
}
const sortBy = (sortList = [], sortOpts = []) =>
{
sortOpts = Array.isArray(sortOpts) ? sortOpts : [sortOpts];
sortOpts = sortOpts.map(o => typeof o === "string" ? { field: o, dir:"asc" } : o.dir ? o : { ...o, dir: "asc" } );
sortOpts.forEach(o => o.dir = o.dir.toLowerCase() === "asc" ? 1 : -1);
return list.sort(compareValues.bind(null, sortOpts));
};
const groupBy = (groupList = [], groupByField) =>
{
const groups = [];
groupList.forEach(l =>
{
let g = groups.filter(g => g.key === l[groupByField]).pop();
if(!g)groups.push({ key: l[groupByField], list: [l] });
else g.list.push(l);
});
return groups.reduce((prev, cur) => prev.concat(cur.list), []);
};
const toS = (ks, ar) => {
if(!Array.isArray(ks))ks = [ks];
return ar.map((o, i) => i+": "+ks.map(k => o[k]).join(', ')).join('\r\n');
}
console.log(`ordered by 'c'\r\n\r\n`+toS('c',
sortBy(list, 'c')));
console.log(`ordered by '[c,b]'\r\n\r\n`+toS(['c', 'b'],
sortBy(list, ['c', { field: 'b', dir:"desc" }])));
console.log(`ordered by 'd'\r\n\r\n`+toS('d',
sortBy(list, 'd')));
console.log(`ordered by '[z,d]'\r\n\r\n`+toS(['z','d'],
sortBy(list, ['z','d'])));
console.log(`ordered by 'd' group by 'z'\r\n\r\n`+toS(['z','d'],
groupBy(sortBy(list, 'd'), 'z')));
console.log(`ordered by 'a'\r\n\r\n`+toS('a',
sortBy(list, 'a')));
console.log(`ordered by ['a','b','c','d'] group by 'z'\r\n\r\n`+toS(['z','a','b','c','d'],
groupBy(sortBy(list, ['a','b','c','d']), 'z')));
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment