Reputation: 1
Currently I have an array that I want to sort by 3 keys. For simplicity, the array looks like this:
bArray = [
{StartDate:"Mar 1, 2017", ID:"ABC-001", Serial:"10000", Qty: "1"},
{StartDate:"Jun 3, 2017", ID:"CDE-001", Serial:"10004", Qty: "1"},
{StartDate:"Mar 1, 2017", ID:"ABC-002", Serial:"10001", Qty: "3"},
{StartDate:"Apr 2, 2017", ID:"CDE-001", Serial:"10003", Qty: "1"},
{StartDate:"Mar 1, 2017", ID:"ABC-001", Serial:"10002", Qty: "1"},
]
I want to sort by ascending in all 3 keys. First by Date, then by ID, then by Serial.
I managed to get it working for Date and ID, however, when I add Serial comparison in the code, I get unexpected results, where the ID and Serial may have anomalies. For example it may be sorted like this when I run the code:
bArray = [
{StartDate:"Mar 1, 2017", ID:"ABC-001", Serial:"10000", Qty: "1"},
{StartDate:"Mar 1, 2017", ID:"ABC-002", Serial:"10001", Qty: "3"},
{StartDate:"Mar 1, 2017", ID:"ABC-001", Serial:"10002", Qty: "1"},
{StartDate:"Apr 2, 2017", ID:"CDE-001", Serial:"10003", Qty: "1"},
{StartDate:"Jun 3, 2017", ID:"CDE-001", Serial:"10004", Qty: "1"}
]
The second and third lines should be reversed because ID should take precedence over Serial.
My code is as follows:
bArray.sort(function (c,d){
if (c.StartDate > d.StartDate) { return 1; }
else if (d.StartDate < c.StartDate) { return -1; }
if (c.ID > d.ID) { return 1; }
else if (d.ID < c.ID) { return -1; }
if (c.Serial > d.Serial) { return 1; }
else if (d.Serial < c.Serial) { return -1; }
else { return 0; }
});
I'd like to also mention that the array I'm sorting is over 100+ lines.
Any insight is much appreciated.
Thanks, Vincent
Upvotes: 0
Views: 110
Reputation: 122077
To sort by date you should parse dates, then you can use localeCompare
for strings and finally change Serial
to numbers.
var arr = [
{StartDate:"Mar 1, 2017", ID:"ABC-001", Serial:"10000", Qty: "1"},
{StartDate:"Jun 3, 2017", ID:"CDE-001", Serial:"10004", Qty: "1"},
{StartDate:"Mar 1, 2017", ID:"ABC-002", Serial:"10001", Qty: "3"},
{StartDate:"Apr 2, 2017", ID:"CDE-001", Serial:"10003", Qty: "1"},
{StartDate:"Mar 1, 2017", ID:"ABC-001", Serial:"10002", Qty: "1"},
]
arr.sort(function(a, b) {
return Date.parse(a.StartDate) - Date.parse(b.StartDate) ||
a.ID.localeCompare(b.ID) || +a.Serial - +b.Serial
});
console.log(arr)
Upvotes: 0
Reputation: 49883
Your comparisons are all of the form
if ( c.X > d.X ) { return 1; }
else if ( d.X < c.X ) { return -1; }
This will never return -1; if c.X > d.X, then d.X < c.X, but you will have already returned 1.
Instead, you should have c
and d
in the same order:
if ( c.X > d.X ) { return 1; }
else if ( c.X < d.X ) { return -1; }
// -------^-----^
(Or you could keep them reversed in the else
and use >
instead of <
.)
Upvotes: 2