How to correctly sort these type of array?

59 Views Asked by At

I am in trouble with this sort. I have an array containing values like this:

array = [ {SortTime : 123456, Operation : Assigning}, {SortTime : 4567 , Operation: Assigning}, {SortTime : 123456 , Operation: Assigned} ]; 

So if I compare array[0] and array[2] I would like to keep the order so that I have "Assigning" before of "Assigned"

Everyone of these number is an epoch number so I need that if the algorithm works with two equals numbers it leave the same initial order for these two numbers (if I have array[4] = 12345 and array[5] = 12345, I want that array[4] and array[5] don't become array[5] and array[4] in the order).

    array.sort(function(a, b) {
        if (a.val.SortTime === b.val.SortTime) {
            return -1;
        } else {
            return a.val.SortTime - b.val.SortTime;
        }
    });

This doens't work because often make swap of position between equals number. I am sorry if my explanation is bad. Thank you in advance!

3

There are 3 best solutions below

0
On BEST ANSWER

You could add to the objects an index property and sort by time and then by index, to keep the relation of same time items.

The result is a stable result, because of the taken index.

var array = [
        { SortTime: 123456, Operation: 'Assigning', index: 0 },
        { SortTime: 4567, Operation: 'Assigning', index: 1 },
        { SortTime: 123456, Operation: 'Assigned', index: 2 }
    ]; 

array.sort(function (a, b) {
    return a.SortTime - b.SortTime || a.index - b.index;
});

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0
On

What you want is a stable sort. See Wikipedia for a list of stable sort algorithms

Here's a merge sort implementation from Rosetta Code:

function merge(left, right, arr) {
  var a = 0;
 
  while (left.length && right.length) {
    arr[a++] = (right[0] < left[0]) ? right.shift() : left.shift();
  }
  while (left.length) {
    arr[a++] = left.shift();
  }
  while (right.length) {
    arr[a++] = right.shift();
  }
}
 
function mergeSort(arr) {
  var len = arr.length;
 
  if (len === 1) { return; }
 
  var mid = Math.floor(len / 2),
      left = arr.slice(0, mid),
      right = arr.slice(mid);
 
  mergeSort(left);
  mergeSort(right);
  merge(left, right, arr);
}
 
var arr = [1, 5, 2, 7, 3, 9, 4, 6, 8];
console.log(arr);
mergeSort(arr)
console.log(arr);

0
On

There is working example at JSBin

var arr = [ 
     { 
       SortTime: 123456, 
       Operation: 'first operator'
     }, {
       SortTime: 4567,
       Operation: Assigning
     }, {
       SortTime: 123456,
       Operation: 'second operator'
     }];

var copy = [...arr];

copy.sort(function(a, b) {
    if (a.val.SortTime === b.val.SortTime) {
        return arr.indexOf(a) - arr.indexOf(b);
    } else {
        return a.val.SortTime - b.val.SortTime;
    }
});