custom sorting v-data-table with null values last - javascript

I have a v-data-table in vueJS that contains some numeric columns and some string columns.
In each column, some of the values are null.
I am trying to create a custom sorting function that will place null values last.
This is what I tried so far:
<v-data-table
:headers="[
{ text: 'Name', value: 'name' },
{ text: 'Date of Birth', value: 'dateofbirth_fmt' },
{ text: 'Team', value: 'team_name' },
{
text: 'dp1 (string)',
value: 'dp1',
},
{
text: 'dp2 (Numeric),
value: 'dp2',
}
]"
:items="filteredPlayersData"
item-key="_id"
class="elevation-1"
:custom-sort="customSort"
/>
and this function
customSort(items, index, isDesc) {
items.sort((a, b) => {
if (!isDesc[0]) {
return (a[index] != null ? a[index] : Infinity) >
(b[index] != null ? b[index] : Infinity)
? 1
: -1;
} else {
return (b[index] != null ? b[index] : -Infinity) >
(a[index] != null ? a[index] : -Infinity)
? 1
: -1;
}
});
return items;
}
It is working for this numeric column (dp1), but not for the string one (dp2).
Any ideas how to get this work?

Your sorting algorithm is not working correctly for strings.
Imagine that your first string is null, and the second one is 'Jelly bean'.
Instead of null value you are trying to compate Infinity with 'Jelly bean'.
This comparison will be false in both cases:
let a = Infinity;
let b = 'Jelly bean';
console.log(a > b);
console.log(a < b);
It'd be better to use another sorting algorithm.
For example, I've adapted an algorithm from this post:
customSort(items, index, isDesc) {
items.sort((a, b) => {
if (a[index] === b[index]) { // equal items sort equally
return 0;
} else if (a[index] === null) { // nulls sort after anything else
return 1;
} else if (b[index] === null) {
return -1;
} else if (!isDesc[0]) { // otherwise, if we're ascending, lowest sorts first
return a[index] < b[index] ? -1 : 1;
} else { // if descending, highest sorts first
return a[index] < b[index] ? 1 : -1;
}
});
return items;
}
You may test this at CodePen. Works fine for both strings and numbers.

Related

Why does my custom sort() function cannot be accepted in JavaScript?

I tried to upgrade the current custom sort function of JavaScript to create a new order of sorting e.g. (1, 2, 3, 4,..., !##$%^=+, a, A, b, B, c, C)
function getSortOrder(prop) {
return function (a, b) {
if (isSpecialChar(a[prop], 0) || isSpecialChar(b[prop], 0)) {
return sortData(a[prop], b[prop]);
}
if (isNumeric(a[prop], 0) == "number" || isNumeric(b[prop], 0) == "number") {
return getSortNumeric(a[prop], b[prop]);
}
if (isLetter(a[prop], 0) || isLetter(b[prop], 0)) {
return getSortLetter(a[prop], b[prop]);
}
};
}
function getSortLetter(a, b) {
if ((a.charAt(0) === getLowerCase(a, 0)) && (b.charAt(0) === getUpperCase(b, 0))) {
return sortData(a, b);
}
return sortData(a, b);
}
function getSortNumeric(a, b) {
if (typeof a[prop] == "number") {
return (a[prop] - b[prop]);
} else {
return ((a[prop] < b[prop]) ? -1 : ((a[prop] > b[prop]) ? 1 : 0));
}
}
function sortData(a, b) {
if (a.toLowerCase() < b.toLowerCase()) {
return -1;
} else if (a.toLowerCase() > b.toLowerCase()) {
return 1;
} else {
return 0;
}
}
/**
* Function that is used for the ascending order of number
*
*/
const sortNumberData = (a, b) => a.localeCompare(b, 'en', { numeric: true })
// to check if the data has numeric
function isNumeric(str, index) {
let x = /^[0-9]$/.test(str.charAt(index));
console.log(str, x);
return x;
}
// to determine if the data has neither numeric or letter
function isSpecialChar(str, index) {
return !isNumeric(str, index) && !isLetter(str, index);
}
// to specify the order of letter e.g. (jane doe, Jane Doe, john doe, John doe)
function isLetter(str, index) {
return str.charAt(index).length === 1 && str.match(/[a-z]/i);
}
function getLowerCase(str, index) {
return str.charAt(index).toLowerCase();
}
function getUpperCase(str, index) {
return str.charAt(index).toUpperCase();
}
expected result of Json Values:
List of Users:
123Admin
321user
!testAdmin
#adminData
jane doe
Jane Smith
john doe
John Doe
Current results of Json Values:
List of Users:
!testAdmin
#adminData
123Admin
321user
Jane Smith
jane doe
john doe
It still follows the Ascii default order of sort.
The approach suggested by Nina Scholz is more concise, but here is what was wrong with your original code:
Your isLetter function does not return the correct result. Using the RegExp.test method as below would fix that:
function isLetter(str, index) {
return str.charAt(index).length === 1 && /^[a-z]/i.test(str);
}
Your getSortOrder function also does not handle sorting correctly when comparing characters that belong to different groups (special character / number / letter). To fix that, you could change that function to distinguish when the characters are in the same group versus when they are in different groups:
function getSortOrder(a, b) {
if (isNumeric(a, 0) && isNumeric(b, 0)) return sortData(a, b);
if (isSpecialChar(a, 0) && isSpecialChar(b, 0)) return sortData(a, b);
if (isLetter(a, 0) && isLetter(b, 0)) return sortData(a, b);
if (isNumeric(a, 0)) return -1;
if (isLetter(a, 0)) return 1;
if (isSpecialChar(a, 0)) {
if (isNumeric(b, 0)) return 1;
return -1;
}
}
Finally, the sortData function does not distinguish between lower and upper case. It would need to do something like this:
function sortData(a, b) {
const aLower = a[0].toLowerCase();
const bLower = b[0].toLowerCase();
if (aLower === bLower) {
if (a[0] === aLower && b[0] !== bLower) return -1;
if (a[0] !== aLower && b[0] === bLower) return 1;
return 0;
}
if (aLower < bLower) return -1;
if (aLower > bLower) return 1;
return 0;
}
You could take a brute force approach with an string/object for the wanted order.
This appriach iterate each pair of strings and check any character by getting the order until finding different characters.
const
chars = ' 0123456789!##$%^=+abcdefghijklmnopqrstuvwxyz',
order = Object.fromEntries(Array.from(chars, ((c, i) => [c, i + 1]))),
sort = (a, b) => {
for (let i = 0, l = Math.min(a.length, b.length); i < l; i++) {
const r = order[a[i].toLowerCase()] - order[b[i].toLowerCase()];
if (r) return r;
}
return a.length - b.length;
},
sortBy = (fn, k) => (a, b) => fn(a[k], b[k]),
data = [{ name: 'abcd' }, { name: 'abc' }, { name: 'John Doe' }, { name: '!testAdmin' }, { name: '#adminData' }, { name: '123Admin' }, { name: '321user' }, { name: 'Jane Smith' }, { name: 'jane doe' }, { name: 'john doe' }];
data.sort(sortBy(sort, 'name'));
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here's a function that can be used in a sort.
It starts with finding the index of the first uncommon character between the lower case strings.
Then assigns the order (-1,0,+1) depending on a priority, and then the order of the lower case strings.
function newSort(a, b) {
let lca = a.toLowerCase();
let lcb = b.toLowerCase();
let len = Math.min(a.length, b.length);
let i = 0;
// find index of first uncommon character
while(lca[i] === lcb[i] && i<len) i++;
// what priority do the types of the uncommon character get
let prioA = !lca[i] ? 0 : /^\d/.test(lca[i]) ? 1 : /^[a-z]/.test(lca[i]) ? 3 : 2;
let prioB = !lcb[i] ? 0 : /^\d/.test(lcb[i]) ? 1 : /^[a-z]/.test(lcb[i]) ? 3 : 2;
let order = prioA > prioB ? 1 : prioA < prioB ? -1
: lca > lcb ? 1 : lca < lcb ? -1 : 0;
return order
}
const stringArray = [
"1!a", "1a!", "!1a", "!a1", "a!1", "a1!"
, "Jane Smith" , "jane doe" , "john doe"
, "abcX", "ABC", "DEFy", "defx"
];
let sortedStringArray = stringArray.sort(newSort);
console.log(sortedStringArray);

How to convert a string into dot notation for array selector

I am trying to optimize a function that will sort a multidimensional array based on user preferences. (id, name, timestamp etc).
Instead of creating many different functions i want to combined them all into one. For example see the code bellow. Instead of making 2 different functions i want to be able to pass name or timeCreated strings to it but i don't know how to convert a string into dot notation.
compareName (a, b) {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
},
compareCreated (a, b) {
if (a.timeCreated < b.timeCreated) {
return -1;
}
if (a.timeCreated > b.timeCreated) {
return 1;
}
return 0;
}
Because some values could be null i found this function that takes care of things better than the above code...I just need to figure out a way to pass my array selector to the a and b.
alphabetically(ascending) {
return function (a, b) {
// equal items sort equally
if (a === b) {
return 0;
}
// nulls sort after anything else
else if (a === null) {
return 1;
}
else if (b === null) {
return -1;
}
// otherwise, if we're ascending, lowest sorts first
else if (ascending) {
return a < b ? -1 : 1;
}
// if descending, highest sorts first
else {
return a < b ? 1 : -1;
}
};
}
You can use [] notation and accept one extra parameter in your function
alphabetically(ascending) {
return function (a, b, prop) {
// equal items sort equally
if (a[prop] === b[prop]) {
return 0;
}
// nulls sort after anything else
else if (a[prop] === null) {
return 1;
}
else if (b[prop] === null) {
return -1;
}
// otherwise, if we're ascending, lowest sorts first
else if (ascending) {
return a[prop] < b[prop] ? -1 : 1;
}
// if descending, highest sorts first
else {
return a[prop] < b[prop] ? 1 : -1;
}
};
}

Custom sorting array of objects

I have an array of objects like so for example:
[ {
id: '-1'
},
{
id: '10'
},
{
id: '1234'
},
{
id: '1235'
},
{
id: '-1'
} ]
I would like to sort this array so that it is ordered by the ids ascending (smallest to largest), however I would like objects that have the id of '-1' to be sent to the back of the array. So I tried this:
const arr = [ { id: '-1' }, { id: '10'}, { id: '1234' }, { id: '1235' }, { id: '-1' } ]
arr.sort((a, b) => {
if (parseInt(a.id) === -1 || parseInt(b.id) === -1) return 1;
if (parseInt(a.id) - parseInt(b.id)) return -1;
});
console.log(arr);
As you can see from the snippet above it sorts them successfully ascending however it doesn't successfully move ids with '-1' to the back of the array.
Why does this happen? What am I doing wrong?
You could take the function with a check for the items which should be sorted to bottom.
var array = [{ id: '-1' }, { id: '10' }, { id: '1234' }, { id: '1235' }, { id: '-1' }];
array.sort((a, b) => (a.id === '-1') - (b.id === '-1') || a.id - b.id);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
How sorting works
First, let's take a look at what .sort expects you to feed it.
Given paramaters (a, b) -- we should return
< 0 if a < b
> 0 if a > b
How you did the sorting
Let's take a look at your first line
if (parseInt(a.id) === -1 || parseInt(b.id) === -1) return 1;
-1 means "a is smaller". But that might not be true. It might be that a (not b) is -1, and is bigger, yet we're always telling JavaScript to send a to the back when that's what we should be doing to b.
Instead, we want to return -1 when b is -1, but +1 when a is -1. It doesn't really matter what we return if they're both -1.
In JavaScript, any number except for 0 is truthful. Let's take a look at your next line.
if (parseInt(a.id) - parseInt(b.id)) return -1;
If a - b is 0, we don't return anything in this callback. If it isn't 0, we always say that a < b.
Notice that never do we say that b < a -- so if such an event were to occur, we couldn't handle it and would sort it incorrectly.
How to sort correctly
Fetch IDs
const aID = parseInt(a.id)
const bID = parseInt(b.id)
Is a or b -1?
if(aID === -1) return +1;
if(bID === -1) return -1;
Which is bigger, a or b
If you assume that a and b are not -1, then we can simply subtract a - b. Why? If a is bigger than b, then the subtraction will create a positive number to say b < a. If a is less than b, then the subtraction will create a negative number, to say a < b.
return aID - bID
All together
const arr = [ { id: '-1' }, { id: '10'}, { id: '1234' }, { id: '1235' }, { id: '-1' } ]
arr.sort((a, b) => {
const [aID, bID] = [parseInt(a.id), parseInt(b.id)]
if(aID === -1) return +1
if(bID === -1) return -1
return aID - bID
});
console.log(arr);
Golfing
It might be helpful to make things shorter. Another answer, by #Nina Scholz, helpfully showed a much shorter version. I thought it might be useful to explain why this works.
return (a.id === '-1') - (b.id === '-1') || a.id - b.id
What is x || y
x || y means:
if x is truthful, return x.
if x isn't truthful, return y.
What is (aID === -1)
This means true if aID is -1, and false otherwise
What is (aID === -1) - (bID === -1)
How can you subtract true and false? true will be interpreted as 1, and false as 0.
aID = -1, bID = not
This value will be 1 - 0, or +1
aID = not, bID = -1
This value will be 0 - 1, or -1
aID = -1, bID = -1
Remember, it doesn't matter what we return if the two values are the same
aID = not, bID = not
0 - 0. This is 0. This is not a truthful value. So we go into the || bit. Which, in that answer, has the second bit be aID - bID, as described above. It's very clever and very short, though might not be as readable.

Sorting a float number against a string?

I think I finally found the source of an irritating problem. I am sorting an array of objects by the price of a product and sometimes the product price is not available denoted an "N/A". I am expecting all the values of "N/A" to be put last in the total sort order...but its not turning out that way. It seems to work for a bit, all prices listed first and then prices and N/A's are interspersed towards the bottom of the sort. How/What can I do to solve this issue?
var arr = [
{id:0,vendor:'ACompany',price:'10.82'},
{id:1,vendor:'ZCompany',price:'10.00'},
{id:2,vendor:'LCompany',price:'9.82'},
{id:3,vendor:'DCompany',price:'N/A'},
{id:4,vendor:'WCompany',price:'11.82'},
{id:5,vendor:'RCompany',price:'N/A'},
{id:6,vendor:'HCompany',price:'10.83'},
{id:7,vendor:'MCompany',price:'10.72'},
{id:8,vendor:'XCompany',price:'9.92'},
{id:9,vendor:'ICompany',price:'N/A'},
{id:10,vendor:'GCompany',price:'10.82'},
] ;
function sortArr(key) {
arr.sort(function(a,b) {
var x = a[key]; var y = b[key] ;
if (key == "vendor") {
return ((x<y) ? -1 : ((x > y) ? 1: 0)) ;
} else {
return parseFloat(x) - parseFloat(y) ;
}
})
}
sortArr('price') ; // when sorting by 'vendor', it works fine.
for (x=0;x<arr.length;x++) {
console.log(arr[x].vendor+ ": " +arr[x].price) ;
}
The Sort output is:
LCompany: 9.82
XCompany: 9.92
ZCompany: 10.00
MCompany: 10.72
ACompany: 10.82
GCompany: 10.82
DCompany: N/A
ICompany: N/A
HCompany: 10.83
WCompany: 11.82
RCompany: N/A
And I know I can't try to parse the prices as strings, the 'N/A's will be last, but $10 values will be listed before $9 values.
You can first sort it by not NaN values and then by price values.
var arr = [{id:0,vendor:'ACompany',price:'10.82'},{id:1,vendor:'ZCompany',price:'10.00'},{id:2,vendor:'LCompany',price:'9.82'},{id:3,vendor:'DCompany',price:'N/A'},{id:4,vendor:'WCompany',price:'11.82'},{id:5,vendor:'RCompany',price:'N/A'},{id:6,vendor:'HCompany',price:'10.83'},{id:7,vendor:'MCompany',price:'10.72'},{id:8,vendor:'XCompany',price:'9.92'},{id:9,vendor:'ICompany',price:'N/A'},{id:10,vendor:'GCompany',price:'10.82'}];
arr.sort((a, b) => {
let aN = +a.price, bN = +b.price;
return !isNaN(bN) - !isNaN(aN) || aN - bN
})
console.log(arr)
Your solution is close, but needs to handle non-numeric input as a special exception. You can detect if the string is non-numeric as follows: isNaN(parseFloat("N/A")) == true, isNaN(parseFloat("3.0")) == false.
The problem is because NaN has no ordering. NaN < NaN == false, NaN > NaN == false, and NaN == NaN == false.
So before you decide to sort numerically with parseFloat(x) - parseFloat(y) in your code, check for that condition and use a different ordering of your choosing.
var arr = [
{id:0,vendor:'ACompany',price:'10.82'},
{id:1,vendor:'ZCompany',price:'10.00'},
{id:2,vendor:'LCompany',price:'9.82'},
{id:3,vendor:'DCompany',price:'N/A'},
{id:4,vendor:'WCompany',price:'11.82'},
{id:5,vendor:'RCompany',price:'N/A'},
{id:6,vendor:'HCompany',price:'10.83'},
{id:7,vendor:'MCompany',price:'10.72'},
{id:8,vendor:'XCompany',price:'9.92'},
{id:9,vendor:'ICompany',price:'N/A'},
{id:10,vendor:'GCompany',price:'10.82'},
] ;
function sortArr(key) {
arr.sort(function(a,b) {
var x = a[key]; var y = b[key] ;
if (key == "vendor") {
return ((x<y) ? -1 : ((x > y) ? 1: 0)) ;
} else {
return isNaN(+x) ? 1 : isNaN(+y) ? -1 : parseFloat(x) - parseFloat(y) ;
}
})
}
sortArr('price') ; // when sorting by 'vendor', it works fine.
for (x=0;x<arr.length;x++) {
console.log(arr[x].vendor+ ": " +arr[x].price) ;
}
This solution is slightly more robust than just handling 'N/A', since it will also put any non-numeric input at the bottom, though not in a specified order.
Try this custom sorter instead.
In short, numeric prices will be sorted at the top of the array and all N/A price types will be sorted down to the bottom. I'd recommend reading about custom sorters here...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
var arr = [
{id:0,vendor:'ACompany',price:'10.82'},
{id:1,vendor:'ZCompany',price:'10.00'},
{id:2,vendor:'LCompany',price:'9.82'},
{id:3,vendor:'DCompany',price:'N/A'},
{id:4,vendor:'WCompany',price:'11.82'},
{id:5,vendor:'RCompany',price:'N/A'},
{id:6,vendor:'HCompany',price:'10.83'},
{id:7,vendor:'MCompany',price:'10.72'},
{id:8,vendor:'XCompany',price:'9.92'},
{id:9,vendor:'ICompany',price:'N/A'},
{id:10,vendor:'GCompany',price:'10.82'}
];
arr.sort(function(a, b) {
if (a.price == b.price) return 0;
if (a.price == "N/A") return 1;
if (b.price == "N/A") return -1;
return a.price - b.price;
});
console.log(arr);
You could check if the property has a string and get the delta of the comparison fo a chained retuen value.
var array = [{ id: 0, vendor: 'ACompany', price: '10.82' }, { id: 1, vendor: 'ZCompany', price: '10.00' }, { id: 2, vendor: 'LCompany', price: '9.82' }, { id: 3, vendor: 'DCompany', price: 'N/A' }, { id: 4, vendor: 'WCompany', price: '11.82' }, { id: 5, vendor: 'RCompany', price: 'N/A' }, { id: 6, vendor: 'HCompany', price: '10.83' }, { id: 7, vendor: 'MCompany', price: '10.72' }, { id: 8, vendor: 'XCompany', price: '9.92' }, { id: 9, vendor: 'ICompany', price: 'N/A' }, { id: 10, vendor: 'GCompany', price: '10.82' }];
array.sort(function (a, b) {
return (a.price === 'N/A') - (b.price === 'N/A') || a.price - b.price;
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Do you really need that N/A's in your output? Filter them out _.filter(arr, ({price}) => price !== 'N/A') and then pass the result to a sort function. A sort function shouldn't know about N/A I guess, it should just do the sorting.
You should check isNaN(parseFloat(x)) and isNaN(parseFloat(y)) before returning the result : if one is NaN then put it last

Sort array first by string and then by date

Well, I have an array objects with random values,
Ex.
var value = [
{"date":"06/11/2017","status":"B"},
{"date":"06/11/2017","status":"B"},
{"date":"15/05/2017","status":"R"},
{"date":"15/05/2017","status":"R"},
{"date":"14/05/2018","status":"R"},
{"date":"05/05/2017","status":"R"},
{"date":null,"status":"W"},
{"date":null,"status":"W"},
{"date":null,"status":"W"},
{"date":"05/11/2017","status":"B"},
{"date":"27/07/2017","status":"R"},
{"date":"14/05/2018","status":"R"},
{"date":"27/07/201","status":"R"},
{"date":"14/05/2018","status":"R"},
{"date":"26/02/2018","status":"R"},
{"date":null,"status":"W"}
];
I wanted to sort this array firstly by key status & then by key date as,
Output:
var result = [
{"date":"05/11/2017","status":"B"},
{"date":"06/11/2017","status":"B"},
{"date":"06/11/2017","status":"B"},
{"date":"05/05/2017","status":"R"},
{"date":"15/05/2017","status":"R"},
{"date":"15/05/2017","status":"R"},
{"date":"27/07/2017","status":"R"},
{"date":"14/05/2018","status":"R"},
{"date":"14/05/2018","status":"R"},
{"date":"14/05/2018","status":"R"},
{"date":"26/02/2018","status":"R"},
{"date":"27/07/2018","status":"R"},
{"date":null,"status":"W"},
{"date":null,"status":"W"},
{"date":null,"status":"W"},
{"date":null,"status":"W"}
];
/*I tried few generic code to sort, */
var result = value.sort(function (a, b) {
var aValue = (a.date) ? a.date: 0;
var bValue = (b.date) ? b.date: 0;
return a.status - b.status || aValue - bValue;
});
I referred few examples SO Example but not getting expected output. Please suggest me best way to get this.
Would this work?
value = value.sort(function (a, b) {
if (a === b || (a.status === b.status && a.date === b.date)) return 0;
if (a.status > b.status) return 1;
if (a.status < b.status) return -1;
if (a.date > b.date) return 1;
if (a.date < b.date) return -1;
})
return a.status - b.status || aValue - bValue;
The values you are dealing with are not numbers! You can't subtract one from the other.
Also: Don't use nested ternary operators. It makes it very hard to understand the code.
Use if statements. They are much more readable.
I think this is what you are looking for, but your description of the problem isn't clear. This should, however, show you the principles so you can tweak it as you want.
const a_is_first = -1;
const b_is_first = 1;
function compare(a, b) {
// Sort and group by status first. Sort by date within the statuses.
if (a.status < b.status) {
return a_is_first;
} else if (a.status > b.status) {
return b_is_first;
} else { // They are the same
var a__date = convert_to_a_date_object(a.date);
var b__date = convert_to_a_date_object(b.date);
if (a__date < b__date) {
return a_is_first;
} else if (a__date > b__date) {
return b_is_first;
} else {
return 0;
}
}
}
value.sort(compare);
The implementation of convert_to_a_date_object is left as an exercise for the reader. Remember it has to handle null.
Please see if this helps
value.sort(function(a, b) {
var nameA = a.status.toUpperCase(),
nameB = b.status.toUpperCase();
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
}).sort(function(a, b) {
return new Date(b.date) - new Date(a.date);
});
You could take status for sorting and if equal take a date string in ISO 8601 notation for sorting. ISO 6801 allowes to use a sorting by string without taking a date object.
var array = [{ date: "06/11/2017", status: "B" }, { date: "06/11/2017", status: "B" }, { date: "15/05/2017", status: "R" }, { date: "15/05/2017", status: "R" }, { date: "14/05/2018", status: "R" }, { date: "05/05/2017", status: "R" }, { date: null, status: "W" }, { date: null, status: "W" }, { date: null, status: "W" }, { date: "05/11/2017", status: "B" }, { date: "27/07/2017", status: "R" }, { date: "14/05/2018", status: "R" }, { date: "27/07/2017", status: "R" }, { date: "14/05/2018", status: "R" }, { date: "26/02/2018", status: "R" }, { date: null, status: "W" }];
array.sort(function (a, b) {
function getDate(d) {
return d ? d.replace(/(..)\/(..)\/(....)/, '$3-$2-$1') : '';
}
return a.status.localeCompare(b.status) || getDate(a.date).localeCompare(getDate(b.date));
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Your date is under format "dd/mm/yyyy". You can use Date.parse("11/05/2017") (with format "mm/dd/yyyy", see parse for more formats) to return the number of milliseconds and compare. For the status, you can use status.charCodeAt(0) to get ASCII value and compare.
Assuming that you have a good date format, here is the solution:
value.sort(function(a, b) {
var diff = Date.parse(a.date) - Date.parse(b.date);
if (diff === 0) {
return a.status.charCodeAt(0) - b.status.charCodeAt(0);
}
return diff;
});
Hope it helps.

Categories