DEV Community

John Muthua
John Muthua

Posted on • Edited on

SORTing => The weird parts

Image description
As you realize the sort function performs mutations on the original array. This more often than not leads to bugs that are difficult to pin-point their origin and produce erroneous results.

There are various methods that one can apply to ensure that bugs do not arise in the process as using test, but in this article, we are solely interested in the possible programming errors that might arise when using sort.
Lets elaborate this using a simple method of sorting arrays in both ascending and descending order with the assumption that the array contains only numbers.

Pit Fall 1: In Functions

One of the simplest method is the use of the sort function directly as:
Given the array [12,21,56,1,88,3,2,45] to sort from the largest to the smallest

let arr = [12, 21, 56, 1, 88, 3, 2, 45];
const largeToSmall = (arr) => {
  return arr.sort((a, b) => a - b);
};
console.log(largeToSmall(arr)); //[1,2,3,12,21,45,56,88]
Enter fullscreen mode Exit fullscreen mode

The code works as expected, lets take the code a little further by adding a smallest to largest conversion

let arr = [12, 21, 56, 1, 88, 3, 2, 45];
function fnOrderArr(arr) {
  const smallToLarge = arr.sort((a, b) => a - b);
  const largeToSmall = arr.sort((a, b) => b - a);
  console.log(largeToSmall); //[88,56,45,21,12,3,2,1]
  console.log(smallToLarge); //[88,56,45,21,12,3,2,1]
}
fnOrderArr(arr);
Enter fullscreen mode Exit fullscreen mode

Notice that largeToSmall is working fine as the array is arranged from the largest to the smallest but as soon as we hit the smallToLarge as we expect the results to be [1,2,3,12,21,45,56,88] but we got [88,56,45,21,12,3,2,1]. Whats going on?

Note that sort() function performs a mutable operation on our array. This means the function literally reorders the array elements in the array.

In our program:

Step 1: Original Array

  • Our original array is [12, 21, 56, 1, 88, 3, 2, 45]

Step 2: Arrange by ascending Order

  • After our smallToLarge operation the original array changes to [1,2,3,12,21,45,56,88]

Step 3: Arrange by Descending Order

  • Now the original array is [1,2,3,12,21,45,56,88] and by trying to order the function in descending order, there seem to develop a bug as it still resorts to [1,2,3,12,21,45,56,88] showing clearly that the sort function fails to perform as expected.

Pit Fall 2: In Classes using Static Methods

The sort function display similar erroneous performance when used in classes with static methods

class OrderInt {
  constructor(arr) {
    this.arr = arr;
  }
  static highToLow(arr) {
    const tempArr = arr;
    const highLow = tempArr.sort((a, b) => a - b);
    return highLow;
  }
  static lowToHigh(arr) {
    const tempArr = arr;
    const lowHigh = tempArr.sort((a, b) => b - a);
    return lowHigh;
  }
}

const arr = [23, 745, 166, 333, 221];
const orderDecreasing = OrderInt.highToLow(arr);
const orderIncreasing = OrderInt.lowToHigh(arr);
console.log("Order in Decreasing Order ", orderDecreasing); //[745,333,221,166,23]
console.log("Order in Increasing Order ", orderIncreasing); //[745,333,221,166,23]
Enter fullscreen mode Exit fullscreen mode

Using Classes without Static Methods

Strangely, using classes with normal method seem to work with the sort function working as expected.

class OrderInt {
  constructor(arr) {
    this.arr = arr;
  }
  highToLow(arr) {
    const tempArr = arr;
    const highLow = tempArr.sort((a, b) => a - b);
    return highLow;
  }
  lowToHigh(arr) {
    const tempArr = arr;
    const lowHigh = tempArr.sort((a, b) => b - a);
    return lowHigh;
  }
}
const Order = new OrderInt()
const arr = [23, 745, 166, 333, 221];
console.log("Order in Decreasing Order ", Order.highToLow(arr)); //[23,166,221,333,745 ]
console.log("Order in Increasing Order ", Order.lowToHigh(arr)); //[745,333,221,166,23]
Enter fullscreen mode Exit fullscreen mode

Although the sort function works both when ordering in ascending or descending order, it still mutates the original array

Leave a like ❤️ if you found this useful
Happy coding 🔥 🔥

Top comments (3)

Collapse
 
jonrandy profile image
Jon Randy 🎖️

I was confused when I read this example:

let arr = [12, 21, 56, 1, 88, 3, 2, 45];
function fnOrderArr(arr) {
  const smallToLarge = arr.sort((a, b) => a - b);
  const largeToSmall = arr.sort((a, b) => b - a);
  console.log(smallToLarge); //[1,2,3,12,21,45,56,88]
  console.log(largeToSmall); //[1,2,3,12,21,45,56,88]
}
fnOrderArr(arr);
Enter fullscreen mode Exit fullscreen mode

because from reading it, it was obvious to me that both log statements would show the array sorted from largeToSmall - since it was the last one to modify the array. I doubted myself and double checked... and I'm not going crazy after all. You are right about sort mutating the array, but your conclusion in the example is incorrect.

Collapse
 
cavein254 profile image
John Muthua • Edited

Hi Randy,
Thanks for taking your time to go through the post. As per your suggestions, on the conclusion, I noticed the error and have rectified it. Let me know if that was the error you meant.

console.log(largeToSmall); //[88,56,45,21,12,3,2,1]
console.log(smallToLarge); //[88,56,45,21,12,3,2,1]
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jonrandy profile image
Jon Randy 🎖️

👍