Reputation: 369
Ok I have a section of code that sorts the names it is given alphabetically.
However the code doesnt handle decimals the way I would want.
It orders the name in the following manner (Obv I would rather it incremented numerically):
It would order it:
Here is the code I am using. I do not fully understand the code as it was a snippet I have been using.
function(a, b){
var nameA=a.myname.toLowerCase(), nameB=b.myname.toLowerCase()
if (nameA < nameB) //sort string ascending
return -1
if (nameA > nameB)
return 1
return 0 //default return value (no sorting)
}
Regards, Jonny
Upvotes: 3
Views: 6067
Reputation: 201
Here is a similar solution on another page: Javascript not sorting DECIMAL numbers correctly
The idea is to sort by the string first then the number.
Upvotes: 1
Reputation: 369
Ok I used rlemon's code sample and edited it to the following:
function(a, b) {
var parts = {
a: a.myname.split(' - '),
b: b.myname.split(' - ')
};
if (parts.a[0] == parts.b[0]) // strings are the same
return parseFloat(parts.a[1]) - parseFloat(parts.b[1]); // sort by number
return parts.a[0] > parts.b[0] ? 1 : -1; // sort by string
}
Upvotes: 0
Reputation: 2653
Try this code:
function (x, y) {
x=x.myname;
y=y.myname;
var nameA = x.toLowerCase().split("-")[0],
nameB = y.toLowerCase().split("-")[0]
if (nameA < nameB) //sort string ascending
return -1
if (nameA > nameB) return 1
var floatExtract = /(([1-9][0-9]*\.?[0-9]*)|(\.[0-9]+))([Ee][+-]?[0-9]+)?/;
if (floatExtract.test(x) && floatExtract.test(y)) {
x = x.match(floatExtract)[1];
y = y.match(floatExtract)[1];
if (!isNaN(parseFloat(x)) && !isNaN(parseFloat(y))) {
x = parseInt(x);
y = parseInt(y);
}
return ((x > y) ? 1 : ((x < y) ? -1 : 0));
}
return 0;
}
It splits your string and does a simple comparison with the first portion [before the hyphen], then searches for a float inside of your string and does another sort on the list against that...
Upvotes: 2
Reputation: 795
Like @Steve Wellens suggested in his comment, I modified your existing snippet to compare the text parts first, then in the event of a tie compare the numeric portions of the string, by converting them to float
s. If you would like to sort solely by the numeric portion of the string then @extramaster 's answer should serve you well.
function(a, b){
var parts, textPartA, textPartB, numericPartA, numericPartB;
parts = a.split('-');
textPartA = parts[0];
numericPartA = parseFloat(parts[1]);
parts = b.split('-');
textPartB = parts[0];
numericPartB = parseFloat(parts[1]);
//sort by text first
if(textPartA < textPartB) {
return -1;
}
if(textPartA > textPartB) {
return 1;
}
//text parts are equal, now sort by the numeric parts
if(numericPartA < numericPartB){
return -1;
}
if(numericPartA > numericPartB){
return 1;
}
return 0;
}
@Jonny: A quick example
Upvotes: 2
Reputation: 17667
Demo and here is the source + small explanation:
function fruit_sort(a, b) {
var parts = {
a: a.split('-'),
b: b.split('-')
};
if (parts.a[0] == parts.b[0]) // strings are the same
return parseFloat(parts.a[1]) - parseFloat(parts.b[1]); // sort by number
return parts.a[0] > parts.b[0] ? 1 : -1; // sort by string
}
var arr = ["APPLE - 1.0051",
"APPLE - 1.1071",
"APPLE - 11.1592",
"APPLE - 12.0692",
"BANANA - 1.0051",
"BANANA - 1.1071",
"BANANA - 11.1592",
"BANANA - 12.0692",
"BANANA - 12.1717",
"APPLE - 12.1717",
"APPLE - 2.0186",
"APPLE - 21.1407",
"BANANA - 23.069",
"APPLE - 22.089",
"APPLE - 23.069",
"BANANA - 2.0186",
"BANANA - 21.1407",
"BANANA - 22.089"];
arr.sort(fruit_sort);
console.log(arr);
// outputs
[
"APPLE - 1.0051",
"APPLE - 1.1071",
"APPLE - 2.0186",
"APPLE - 11.1592",
"APPLE - 12.0692",
"APPLE - 12.1717",
"APPLE - 21.1407",
"APPLE - 22.089",
"APPLE - 23.069",
"BANANA - 1.0051",
"BANANA - 1.1071",
"BANANA - 2.0186",
"BANANA - 11.1592",
"BANANA - 12.0692",
"BANANA - 12.1717",
"BANANA - 21.1407",
"BANANA - 22.089",
"BANANA - 23.069"
]
First the function splits the terms up into their text and numerical parts - if the text is even it only sorts on the parseFloat value of the numerical value - otherwise it sorts first by the string value.
Upvotes: 3