As this answer was previously upvoted, I will keep the original answer, but I highly recommend the new implementation of sortBy
which sorts an array and allows multiple sort criteria (through Schwartzian transform) See this gist: sortBy.js
Creating the sorting function
var sortBy = (function () {
const _defaults = {
parser: (x) => x,
desc: false
};
const isObject = (o) => o !== null && typeof o === "object";
const isDefined = (v) => typeof v !== "undefined";
//gets the item to be sorted
function getItem (x) {
const isProp = isObject(x) && isDefined(x[this.prop]);
return this.parser(isProp ? x[this.prop] : x);
}
/**
* Sorts an array of elements
* @param {Array} array: the collection to sort
* @param {Object} options:
* options with the sort rules. It have the properties:
* - {String} prop: property name (if it is an Array of objects)
* - {Boolean} desc: determines whether the sort is descending
* - {Function} parser: function to parse the items to expected type
* @return {Array}
*/
return function (array, options) {
if (!(array instanceof Array) || !array.length)
return [];
const opt = Object.assign({}, _defaults, options);
opt.desc = opt.desc ? -1 : 1;
return array.sort(function (a, b) {
a = getItem.call(opt, a);
b = getItem.call(opt, b);
return opt.desc * (a < b ? -1 : +(a > b));
});
};
}());
Setting unsorted data
var data = [
{date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
{date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
{date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"},
{date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
{date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
{date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
{date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"}
];
Using it
Arrange the array, by "date"
as String
//sort by @date (ascending)
sortBy(data, { prop: "date" });
// first element expected
{ date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }
// last element expected
{ date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
If you want to ignore case sensitive, set the parser
callback:
//sort by @type (ascending)
sortBy(data, {
prop: "type",
// ignore case sensitive
parser: (t) => t.toUpperCase()
});
// first element expected
{ date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash" }
// last element expected
{ date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa" }
If you want to convert the "date"
field as Date
type:
//sort by @date (descending)
sortBy([].concat(data), {
prop: "date",
desc: true,
parser: (d) => new Date(d)
});
// first element expected
{ date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
// last element expected
{ date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }
Thanks to @Ozesh by his feedback, the issue related to properties with falsy values was fixed.