-1

I want to sort an array values in an ascending or descending order without using sort().

I have created a function, however I am not satisfied with it. I believe the code below could be much shorter and more concise.

Please let me know where to modify or you may entirely change the code too. Thank you in advance.


const func = arg => {
    let flip = false;
    let copy = [];

    for(let val of arg) copy[copy.length] = val;    
    for(let i=0; i<arg.length; i++) {
        const previous = arg[i-1];
        const current = arg[i];

        if(previous > current) {
            flip = true;
            copy[i] = previous;
            copy[i-1] = current;
        }
    }

    if(flip) return func(copy);
    return copy;
};

l(func([5,2,8,1,9,4,7,3,6]));

vincent
  • 29
  • 3

1 Answers1

0

If your input is composed of whole numbers, as in the example, pne option is to reduce the array into an object, whose keys are the numbers, and whose values are the number of times those values have occured so far. Then, iterate over the object (whose Object.entries will iterate in ascending numeric key order, for whole number keys), and create the array to return:

const func = arr => {
  const valuesObj = {};
  arr.forEach((num) => {
    valuesObj[num] = (valuesObj[num] || 0) + 1;
  });
  return Object.entries(valuesObj)
    .flatMap(
      ([num, count]) => Array(count).fill(num)
    );
};


console.log(
  func([5,2,8,1,9,10,10,11,4,7,3,6])
);

This runs in O(N) time.

To account for negative integers as well while keeping O(N) runtime, create another object for negatives:

const func = arr => {
  const valuesObj = {};
  const negativeValuesObj = {};
  arr.forEach((num) => {
    if (num >= 0) valuesObj[num] = (valuesObj[num] || 0) + 1;
    else negativeValuesObj[-num] = (negativeValuesObj[-num] || 0) + 1;
  });
  return [
    ...Object.entries(negativeValuesObj).reverse()
      .flatMap(
        ([num, count]) => Array(count).fill(-num)
      ),
    ...Object.entries(valuesObj)
      .flatMap(
        ([num, count]) => Array(count).fill(num)
      )
  ];
};


console.log(
  func([5,2,8,1,-5, -1, 9,10,10,11,4,7,3,6, -10])
);

For non-integer items, you'll have to use a different algorithm with higher computational complexity.

CertainPerformance
  • 313,535
  • 40
  • 245
  • 254
  • Should probably be `integer keys` — "numeric keys" would suggest it includes floats. – Mark Jul 24 '19 at 00:47