My code return a Sorted Array

Continuing the discussion from freeCodeCamp Challenge Guide: Return a Sorted Array Without Changing the Original Array:

arr=[...globalArray]

return arr.sort()

1 Like

Sure, or even simply

one-liner

return […globalArray].sort((a,b)=>a-b);

And (if you were allowed to change the rest of the exercise, which you really shouldn’t:

even shorter one-liner
const nonMutatingSort = (globalArr) => [...globalArr].sort((a,b)=>a-b);

Yes, the spread operator is the ES6 way of doing the same thing as concat(). Works great.

5 Likes

Funny that I did a very similar code and it wouldn’t let me pass lol.

  let newArr = arr;
  return newArr.sort();

You are just sorting arr, because newArr is arr in your code

Computers are extremely stupid things and don’t have concept of “similar” (un)fortunately.

// Similar to math, this block...
let a = b;
return a.doSomething();

// ...equals to this block
let a = b.doSomething();
return a;

// ...equals to this block
return b.doSomething();

// The last one is more correct
// as you don't need to assign variable
// just to return it on the next line

So a quick lesson in how js handles variables. Folks will tell you that primitive and non-primitive data are handled differently, but that’s not entirely accurate.

Primitive data (strings, numbers, boolean values, null, undefined and the like) are immutable. That means, when they are created, they are placed in a location in the browser’s allocated memory, and a variable is pointed to that memory location. If the variable’s value is changed, the location in memory to which it points is changed. The data itself remains in that memory place, until no variables actually point to that location in memory. Thus, that actual data, at that actual memory, is unchanged throughout.

Non-primitive data, which includes Arrays, Objects, Sets, Maps and the like, are done in exactly the same way, mostly. When a variable is set to a new array (like let myArray = []; ), what we’ve done is set a place in that same memory that contains the array’s wrapper, and pointed the variable to that memory position. When an element is added to that empty array, say a string (using myArray.push("Hello world!"); ), then the original memory position remains, but it contains a “note” to js to find the first member of the array at another memory position. So long as we keep adding to that array, our original memory reference remains intact. We aren’t updating the actual variable, it still points to that same array, but we’re altering the contents of the array by pointing to more and more data. Array.sort() simply adjusts the order of those memory position’s pointers - but the original, which the variable points to, is still the same.

That’s a LONG-winded explanation for a simple problem, huh? But there is a point here. See, when you did

let newArr = arr;

you’re telling the variable newArr to point to that same memory location that arr is using. They both point to the same array. And if either one updates the contents of that array, then both of them see it - because they both point to the same starting position for the array container.

If we use something like

let newArr = new Array.from(...arr);
let anotherNewArr = arr.concat();
let aThirdNewArr = [...arr];
let aFourthNewArr = JSON.parse(JSON.stringify(arr) );

… each of the above create a completely new array container, with completely new array contents. The reference to the original is broken. Thus, changing the new contents leaves the original completely unaffected.

12 Likes

Thank you for this explanation snowmonkey, that makes more sense to me now.

2 Likes
return [...arr].sort()

2 Likes

@snowmonkey

Why we used .sort(a,b)=>(a-b); not only .sort() ?

1 Like

If you use sort() function for numbers 1-9 it sort array from lowest to biggest. Try to use perform sort() function for numbers above 9.

My English is quite poor I am sorry for mistakes

1 Like

From the documentation:

If you leave off the comparison function it will sort for example like:

> [1, 2, 10, 20, 100, 200].sort()
[1, 10, 100, 2, 20, 200]

Because the character code for 1 comes before the character code for 2.

4 Likes

return arr.slice().sort((a,b)=>a-b);
will also work great

After working through the Functional Programming JavaScript section, I found myself very much enjoying the syntax of chaining method invocations. Below is the recipe I cooked up.

var globalArray = [5, 6, 3, 2, 9];
function nonMutatingSort(arr) {
  var myArr = [];
  return arr
    .slice()
    .concat(myArr)
    .sort((a, b) => {
      return a - b;
    });
}
nonMutatingSort(globalArray);

I hope this solution helps someone to understand how powerful chaining higher order functions can be for solving complex problems, just as the Functional Programming section states! :smiley:

1 Like

Heres my code:

var globalArray = [5, 6, 3, 2, 9];
function nonMutatingSort(arr) {
  // Only change code below this line
console.log(arr.slice())
return arr.slice().sort(function(a,b){
  return a===b?0:a<b?-1:1
})
  // Only change code above this line
}
nonMutatingSort(globalArray);

I found it easier to use this:

function nonMutatingSort(arr) {
  const newArr = arr.slice()
  return newArr.sort((a,b) => a-b)
}
1 Like

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

1 Like

i simple use slice() and sort() and it works fine

return  arr.slice().sort()

Hey hi @bigobolson, delighted to have you here and solid input!

The slice() will return a new array, so you’re not mutating the original. Very nicely done. :grin:

And the sort works great here as well. In this particular case - but suppose you wanted to sort by date, or by a longer number, or by zip code? In those cases, simply .sort() won’t do what you expect.

.sort() is, by default, sorting the array members as strings. So numbers will be converted to strings, booleans to strings (yes, a true or false will convert to "true" or "false" - open a console and type Boolean(1).toString() or true.toString() if you don’t believe me! :wink: ), any primitive will be converted to a string. If you’re sorting an array of numbers, or dates… this won’t really help you.

3 Likes
var globalArray = [5, 6, 3, 2, 9];
function nonMutatingSort(arr) {
  // Only change code below this line
  return arr.slice().sort(function(a, b){
    return a - b;
  })
return arr;

  // Only change code above this line
}
nonMutatingSort(globalArray);
1 Like

Is there a question in there, or sharing your code? Looks accurate from here. :blush: