Functional Programming: Return a Sorted Array Without Changing the Original ArrayPassed

Tell us what’s happening:

I learnt that sort method mutates an array that is sorted and that one way to avoid this is to concatenate an empty into the being sorted using either slice() or concat() method.
pls can anyone explain to me why this doesn’t work with alphabetical array but does with number array?
for example the code below gives the same output :
‘’’
[“y”, “x”, “u”, “d”, “b”, “a”, “a”]
[“y”, “x”, “u”, “d”, “b”, “a”, “a”]
‘’’
I thought consoleloging alpha should output the original array. But it didn’t. why?
pls I am highly sorry for the mistakes in my first post.

Your code so far


var alpha = ["a", "d", "c", "a", "z", "g"] 
function alphabeticalOrder(arr) {
// Add your code below this line
var newArr = arr.sort();
return newArr.sort(function(a,b){
return a<b ? -1 : 1
})

// Add your code above this line
}
console.log(alphabeticalOrder(alpha));
console.log(alpha);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36.

Challenge: Sort an Array Alphabetically using the sort Method

Link to the challenge:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/functional-programming/sort-an-array-alphabetically-using-the-sort-method

What do you mean, “pls can anyone explain to me why this works with alphabetical array not number array?”

Are you talking about the creating a new array or the sorting?

The creating a new array is the same. But the sort method works non-intuitively for numbers, because the numbers get converted to strings first by default. You can read about the problems here.

Let us know if this still doesn’t answer your question.

1 Like

Tell us what’s happening:

I learnt that sort method mutates an array that is sorted and that one way to avoid this is to concatenate an empty into the being sorted using either slice() or concat() method.
pls would kevinSmith or anyone try to explain to me why this doesn’t work with alphabetical array but does with number array?
for example the code below gives the same output :
‘’’
[“y”, “x”, “u”, “d”, “b”, “a”, “a”]
[“y”, “x”, “u”, “d”, “b”, “a”, “a”]
‘’’
I thought consoleloging alpha should output the original array. But it didn’t. why?
It was noted when I try this with number array that the original array was not mutated, it worked fine. But mutation of the alphabet array is my concern.
pls I am highly sorry for the mistakes in my first post.

Your code so far


var alpha = ["a", "d", "c", "a", "z", "g"] 
function alphabeticalOrder(arr) {
// Add your code below this line
var newArr = arr.sort();
return newArr.sort(function(a,b){
return a<b ? -1 : 1
})

// Add your code above this line
}
console.log(alphabeticalOrder(alpha));
console.log(alpha);

'''

try to explain to me why this doesn’t work with alphabetical array but does with number array?

It’s not clear to me what you mean by “this” in that sentence. Perhaps you could give an example that gives a result you expect for one but not for the other.

I thought consoleloging alpha should output the original array. But it didn’t. why?

It is … sort of. You have to understand what “alpha” is. “alpha” is not an array. “alpha” is a variable that holds a memory address that points to the array stored in memory somewhere else. In JS, we call this a reference type. All reference types (in JS) are objects, including arrays and functions.

So, in this example:

const arr1 = [1, 2, 3];
const arr2 = arr1;
arr2[0] = 'banana';

console.log(arr1);
// ["banana", 2, 3]

console.log(arr2);
// ["banana", 2, 3]

How many arrays are there? There is only 1. And there are two variables that reference that portion of memory. So, if I make changes to the memory that arr1 points to, the array that arr2 points to will be changed because they point to same exact array. There was ever only one.

So, something similar is happening with sort. It is not creating a new array, but is sorting in place. (Some prototype methods do, some don’t.) So, if you do:

var newArr = arr.sort();

You haven’t created a new array, you have created a new reference that points to the same exact section of memory that contains the same array. The old version of the array is copied over with the sorted version. If you wanted to do it without changing the original, you’d have to make a copy, a real copy.

const arr1 = [3, 1, 2];
const arr2 = arr1.slice();
arr2.sort();
console.log(arr1);
// [3, 1, 2]
console.log(arr2);
// [1, 2, 3]

You don’t need to save the return value from sort because it changes the array original.

And you could chain the methods:

const arr1 = [3, 1, 2];
const arr2 = arr1.slice().sort();
console.log(arr1);
// [3, 1, 2]
console.log(arr2);
// [1, 2, 3]

There’s also an ES6 way to do it:

const arr1 = [3, 1, 2];
const arr2 = [...arr1].sort();
console.log(arr1);
// [3, 1, 2]
console.log(arr2);
// [1, 2, 3]

Yes, this is confusing. Don’t get frustrated with this stuff.

Is any of this clear?

Thanks a million @kevinSmith! Your down-to-the-earth explanation really proved helpful in no small measure.
I have also learnt that using this:

return [].concat(arr).sort(function(a,b){.........};

will leave the original array stored in the global variable unmutated.
Thanks

Yes, concat will work, but I think slice is more common for ES5 and now most people do it the ES6 way.