Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is going on in this intermediate stage of Array.sort?

While doing a deep dive on array methods, I decided to take a look at the steps involved in the Array.sort method. Take a look at this code to reverse the order of an array in place:

let arr = [];

for (let i = 1; i < 6; i++) {
  arr.push(i);
}

arr.sort((value1, value2) => {
  console.log(arr);
  console.log(`Comparing ${value1} : ${value2}`);
  return value2 - value1;
});

console.log(arr);

I get this output:

[1, 2, 3, 4, 5]
Comparing 1 : 2
[2, 1, 3, 4, 5]
Comparing 1 : 3
[2, 1, 1, 4, 5]
Comparing 2 : 3
[3, 2, 1, 4, 5]
Comparing 1 : 4
[3, 2, 1, 1, 5]
Comparing 2 : 4
[3, 2, 2, 1, 5]
Comparing 3 : 4
[4, 3, 2, 1, 5]
Comparing 1 : 5
[4, 3, 2, 1, 1]
Comparing 2 : 5
[4, 3, 2, 2, 1]
Comparing 3 : 5
[4, 3, 3, 2, 1]
Comparing 4 : 5
[5, 4, 3, 2, 1]

The first two steps make sense, but look at the third: [2, 1, 1, 4, 5].

Why would this be the behavior when I would expect [2, 3, 1, 4, 5]?

As you can see down the line, this repeated digit phenomenon shows up again and again until the array is finally reversed. What am I missing? It's clearly keeping a copy of the array after each mutation somewhere that isn't in arr.

like image 749
sadq3377 Avatar asked Sep 17 '18 19:09

sadq3377


People also ask

What happens when you sort an array?

sort takes an array and — you guessed it — sorts it in place. No copy of the array is created (as with map , etc.), so the array itself is altered with the sorted values. It can be used with or without a compareFunction , and when one isn't provided, it will automatically sort in ascending order.

What is sorting operation on array explain with example?

Sorting is the process of arranging the elements of an array so that they can be placed either in ascending or descending order. For example, consider an array A = {A1, A2, A3, A4, ?? An }, the array is called to be in ascending order if element of A are arranged like A1 > A2 > A3 > A4 > A5 > ? > An .

In which process data within the array is sorted?

There are many well-known methods by which an array can be sorted, which include, but are not limited to: Selection sort, Bubble sort, Insertion sort, Merge sort, Quicksort, Heapsort, and Counting sort.

When an array is almost sorted in such a situation?

Given an array of n elements, where each element is at most k away from its target position, devise an algorithm that sorts in O(n log k) time. For example, let us consider k is 2, an element at index 7 in the sorted array, which can be at indexes 5, 6, 7, 8, 9 in the given array.


2 Answers

When arrays are small browsers (well...at least chrome and safari and node) use insertion sort. The behavior you are seeing is the result of looking at the array in the middle of the insertion sort loop. You can reproduce it with:

let arr = [ 1, 2, 3, 4, 5];

function InsertionSort(a, comparefn) {
    let from = 0
    let to = a.length
    for (var i = from + 1; i < to; i++) {
      var element = a[i];
      for (var j = i - 1; j >= from; j--) {
        var tmp = a[j];
        var order = comparefn(tmp, element); //<-- your console.log is peaking at the array here
        if (order > 0) {
          a[j + 1] = tmp;
        } else {
          break;
        }
      }
      a[j + 1] = element;
    }
  };

InsertionSort(arr,  (a,b) => {
    console.log(arr.join(","))
    return b-a
})
console.log(arr)

Just keep in mind that this is not a required implementation so you shouldn't necessarily count on this behavior.

like image 159
Mark Avatar answered Oct 29 '22 22:10

Mark


To add to @mark-meyer answer. There is no specification for browsers on how to compare numbers based on callback provided to sort method.

For example, Array.sort() is used sometimes to uniformly randomize array with:

var shuffledArr = arr.sort(() => (Math.random() - 0.5))

In this case

If comparefn is not undefined and is not a consistent comparison function for the elements of this array (see below), the sort order is implementation-defined.

https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.sort

You can check this page to see randomization results inside your browser: http://siri0n.github.io/attic/shuffle-comparison/index.html. Compare Chrome and Firefox. More than this, Firefox would choose different sorting algorithms for different field sizes. Not the answer, but I hope an interesting addition to the question.

like image 26
Georgy Avatar answered Oct 29 '22 21:10

Georgy