Reputation: 627
I've written a function that alphabetizes using the the .sort()
method. Presently, the function only works with lowercase letters. How would I fix this function so that uppercase letters are treated the same as lowercase? For instance, C sorts before a, which makes no sense.
Here is my code:
document.getElementById("btn").addEventListener('click', alphabetize);
function alphabetize () {
var output;
var input = document.getElementById('input').value;
input = input.split('').sort().join('');
output = input;
document.getElementById('output').value = output;
}
<input type="text" id="input" /><br />
<input type="text" id="output" /><br />
<button id="btn">Alphabetize String </button>
Upvotes: 1
Views: 120
Reputation: 6796
What you're trying to do is compare and sort letters of mixed case but what JavaScript actually does is compare the Unicode code point values of those letters and sort them accordingly as, to oversimplify, JavaScript doesn't know how characters compare to each other - it's easy for the human brain to see that "C" should come after "a" but how should letters from different alphabets or even non-letter symbols compare to each other?
Converting the letters of the English alphabet to character codes, the uppercase letters A-Z are represented by 65-90 and the lowercase letters a-z are represented by 97-122, which explains why, in your sort()
, "C" is coming before "a" (67<97).
What we need to do is to compare like with like, either all lowercase or all uppercase letters. The simplest way to do this would be to convert your input string .toLowerCase
or .toUpperCase
before applying the sort()
but this will have the undesired result of the output string being in a single case, rather than in the mixed case of the original input.
The solution, therefore, is to convert each character to the same case during the comparison, leaving the original case untouched. We do this by passing a compareFunction
to the sort()
method, like so:
(function(){
var output=function(input){
return input.split("").sort(function(a,b){
return a.toLowerCase()>b.toLowerCase();
}).join("");
};
console.log(output("Charlie"));
console.log(output("Shaggy"));
})();
An alternative method would be to use localeCompare()
to compare the 2 characters without case conversion, which has the added benefit of being able to compare accented characters:
(function(){
var output=function(input){
return input.split("").sort(function(a,b){
return a.localeCompare(b);
}).join("");
};
console.log(output("Charlie"));
console.log(output("Shaggy"));
})();
If ES6 is an option for you, you could use the spread operator to split the string into individual letters and an arrow function for the compareFunction
, like so:
{
const output=input=>[...input].sort((a,b)=>a.toLowerCase()>b.toLowerCase()).join("");
/*ALTERNATIVES*/
//const output=([...input])=>input.sort((a,b)=>a.localeCompare(b)).join("");
//const output=input=>input.split``.sort((a,b)=>a.localeCompare(b)).join("");
console.log(output("Charlie"));
console.log(output("Shaggy"));
}
Note: I have assumed that any string manipulation (e.g., trimming white space) and checks (e.g., zero-length strings, non-letter characters) that need to be performed are already part of your code.
Upvotes: 0
Reputation: 973
Try this:
function alphabetize () {
var output;
var input = document.getElementById('input').value;
input = input.toLowerCase().split('').sort().join('');
output = input;
document.getElementById('output').value = output;
}
//Input: "Charlie"
//Output: "acehilr"
https://jsfiddle.net/fdnnu8Ld/
Upvotes: 2
Reputation: 1991
See the Array.protoype.sort
docs, which includes examples:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
Upvotes: 0