I have a list of Tasks and each task contains the property 'fromPriority'. This property is a string and its values can only be 'HIGH', 'AVERAGE', 'LOW' or a numeric string. I need to order this list by this property, but I need that the numeric strings are ordered first in desceding order. For example, if I have the following values:
['1', '99', '10', 'HIGH', '5', 'LOW']
I want the order to be
['99', '10', '5', '1', 'HIGH', 'LOW']
This may be one possible solution to achieve the desired objective.
Code Snippet
const myDict = { // helper object to assign numeric values for High, Average, Low
'HIGH': 2, 'AVERAGE': 1, 'LOW': 0
};
const customSort = arr => (
[...arr].sort((a, b) => ( // shallow-copy 'arr' and use '.sort()'
a in myDict && b in myDict // if both a & b are High, Average or Low
? myDict[b] - myDict[a] // find difference in their costs (using 'myDict')
: b in myDict // else, if b is either High, Average or Low
? -1 // then, keep b below a
: a in myDict // else, if a is either High, Average or Low
? 1 // then, keep a below b
: +b - +a // else, if both a & b are numeric-strings
)) // convert to number (using '+') and order based on difference
);
const rawData = ['1', '99', '10', 'HIGH', '5', 'LOW'];
console.log(`[${rawData.join(', ')}]`, customSort(rawData));
console.log(
"['15', 'AVERAGE', '20', 'HIGH', '52', 'LOW']",
customSort(['15', 'AVERAGE', '20', 'HIGH', '52', 'LOW'])
);
console.log(
"['31', '49', '17', 'AVERAGE', '25', 'LOW']",
customSort(['31', '49', '17', 'AVERAGE', '25', 'LOW'])
);
console.log(
"['41', 'HIGH', '90', 'LOW', '45', 'AVERAGE']",
customSort(['41', 'HIGH', '90', 'LOW', '45', 'AVERAGE'])
);
console.log(
"['71', '32', '05', 'HIGH', '75', 'LOW']",
customSort(['71', '32', '05', 'HIGH', '75', 'LOW'])
);
Explanation
Inline comments in the above code-snippet provide relevant description of the steps.
This code implements a custom sort function to sort for the condition you have returning 1/-1 means a is greater/smaller than b respectively.
let arr = ['99', '100', '2']
const custom_sort = (a, b) => {
const numericA = !isNaN(a);
const numericB = !isNaN(b);
if (numericA && !numericB) return -1;
if (!numericA && numericB) return 1;
if (numericA && numericB) {
if (parseInt(a) > parseInt(b)) return -1;
return 1;
} else {
if(a==='LOW')return 1;
if(a==='MED'&&b==='HIGH')return 1;
return -1;
}
}
console.log(arr.sort(custom_sort));
Here is a simple solution
function customSort(arr) {
//first sort only the numbers
let newArr = arr
.filter(el => !isNaN(el)) //filter numbers
.sort((a, b) => parseInt(b) - parseInt(a)) //sort numbers
//now the alplabical part
let str = ['HIGH', 'AVERAGE', 'LOW'] //arrange all possible strings
str.forEach(el => (arr.includes(el) ? newArr.push(el) : null)) //push matched items in the newArr
return newArr
}
let input = ['1', '99', '10', 'HIGH', '5', 'LOW']
let output = customSort(input)
console.log(output)