How can I sort an array in ascending order by the elements which are numbers while putting the elements that are strings at the back of the array?
I have tried this but I don't think it's correct(all ql ids that are strings as "NOT_SET", I want to have them at the back of the array (in typescript):
const qaInspectionLinesSorted = _.forEach(qaInspectionLinesGroupedByType, (item => {
return item.sort((ql1, ql2) => {
if (ql1.id.toString() !== "NOT_SET") {
return 0;
}
if (ql1.id.toValue() > ql2.id.toValue()) {
return 1;
} else if (ql1.id.toValue() < ql2.id.toValue()) {
return -1;
}
return 0;
});
}));
An item has this structure if it helps:
_id: UniqueEntityID { value: 9 },
props: {
qaInspectionTypeId: [QAInspectionTypeId],
qaInspectionLineStatusId: [QAInspectionStatusId],
qaInspectionLineNotes: 'HIIIIII',
qaInspectionId: 1
}
CodePudding user response:
Your comparator is returning 0 when ql1.id.toString() !== "NOT_SET" is true, regardless of anything about ql2, which is definitely wrong, because you haven't done a comparison between two elements from the array.
Here's my solution:
function sortStringsLast<T>(arr: T[], key: (x: T) => string | number): T[] {
return arr.sort((x, y) => {
const xKey = key(x), yKey = key(y);
if(typeof xKey === 'string') {
return typeof yKey === 'string' ? 0 : 1;
} else {
return typeof yKey === 'string' ? -1 : xKey - yKey;
}
});
}
I am not sure from your code exactly how you are deriving a sorting key that is either a string or a number, so I wrote a function accepting a key parameter to derive the sorting keys however you want for your own data. Note that when xKey is a string, you only want to return 0 when yKey is also a string; otherwise we return 1 to indicate that x should appear after y in sorted order, because xKey is a string and yKey is a number.
If you did want the strings to be in some specific order, you could easily replace the 0 in the above function with some other comparator, e.g. xKey.localeCompare(yKey).
Test:
const arr = [1, 'foo', 4, 'bar', 3, 'baz', 2];
// [1, 2, 3, 4, "foo", "bar", "baz"]
console.log(sortStringsLast(arr, x => x));
