# Sorting a mixed array of numbers and strings

Hi there!

I had a recent interview question which stumped me:

Q. The following array is a mix of numbers and strings. Sort the array ascending.

``````// Original Array:
[1, 'ss', 11, 2, 'aa']
// Expected Output:
[1, 2, 11, 'aa', 'ss]
``````

I can use the built-in sort function:
`[1, 'ss', 11, 2, 'aa'].sort()`
But the result is incorrect since 2 should be before 11:
`[ 1, 11, 2, 'aa', 'ss' ]`

So, I can use a helper function with sort(), but the output is still incorrect:

``````let myarr = [1, 'ss', 11, 2, 'aa'];
function compareNumbers(a, b) {
return a - b;
}
myarr.sort(compareNumbers);
console.log(myarr);  // returns [ 1, 'ss', 2, 11, 'aa' ]
``````

Is there an elegant way in JavaScript to sort this array?

Always start with code that works and then look for something elegant.

You callback needs to cover 3 cases, right?

1. string vs string
2. string vs number
3. number vs number

What should happen in each case?

3 Likes

Hi @VayaBuzz !

The best way to approach this is to think about how you would solve it as a human.
As a human, you could sort a list of numbers, then a list of letters and combine the two results into one list.

Then you try to translate that into code.

As mentioned, try to focus on a working solution then think about refactoring.

3 Likes

@JeremyLT and @jwilkins.oboe , thank you so much for the quick responses!

Your advice harkens back to good 'ol CS fundamentals which I should not forget-- break things down into smaller problems!

This code seemed to work for me, although it may not be super elegant!

``````// problem:  Sort this array:
let myarr1 = [1, 'ss', 11, 2, 'aa'];
//           expected output:
//           [ 1, 2, 11, 'aa', 'ss' ]
// extra test cases if you need them:
//let myarr2 = ['zzz', 1, 's', 11, 2, 'a', 111];
// solution:
function compareNumbers(a, b) {
//console.log('a: ' + a);
//console.log('b: ' + b);
//console.log('-------');
if (typeof a === 'number' && typeof b === 'number') {
return a - b;
}
// check for num vs string
if (typeof a === 'number' && typeof b === 'string') {
return -1;
}
// check for string vs num
if (typeof a === 'string' && typeof b === 'number') {
return 1;
}
// check for string vs string
if (typeof a === 'string' && typeof b === 'string') {
if (a < b) return -1;
else return 1;
}
return 0;
}
myarr1.sort(compareNumbers);
console.log(myarr1);
``````

Again, thanks everyone for your help! I appreciate you greatly!

2 Likes

Cool Glad you were able to get it working.

Here was my take on it but I am sure there are millions ways to do this ``````let myArr1 = [1, "ss", 11, 2, "aa"];
let myArr2 = ["zzz", 1, "s", 11, 2, "a", 111];
let myArr3 = [56, "awesome", 240, "happy", 6, 89];

function sortArr(arr) {
let numArr = arr.filter((el) => typeof el === "number").sort((a, b) => a - b);
let strArr = arr.filter((el) => typeof el === "string").sort();
return numArr.concat(strArr);
}

console.log(`Unsorted: \${myArr1} Sorted: \${sortArr(myArr1)}`);
console.log(`Unsorted: \${myArr2} Sorted: \${sortArr(myArr2)}`);
console.log(`Unsorted: \${myArr3} Sorted: \${sortArr(myArr3)}`);

``````
3 Likes

What do those return statements do when you check for num vs string, string vs num and string vs string?

I tried a couple approaches. First I went with splitting the list as well, but then I wanted to try a helper function.

This is what I came out with:

``````const helper = (a, b) => ({
'numbernumber': a-b,
'stringnumber': 1,
'numberstring': -1,
'stringstring': a > b ? 1 : -1
}[typeof(a) + typeof(b)]);

a = ['b', 2, 'c', 'a', 1, 3, 'hello', 1009];
a.sort(helper);
console.log(a);
``````
1 Like

@Montin the return statements are following the guidelines of a custom compare function.

``````function compare(a, b) {
if (a is less than b by some ordering criterion) {
return -1;
}
if (a is greater than b by the ordering criterion) {
return 1;
}
// a must be equal to b
return 0;
}
``````

See this site for complete info on how how to write your own comparison function:

Array.sort() uses a default comparison function, but if it doesn’t work the way you like, you can write your own comparison function as we did here, and pass the custom comparison function as a parameter to Array.sort().

Cheers,
Patrick

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.