Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I push an element into array at a sorted index position?

Say I have an array already with these articles, ordered by lowest to highest price:

[
  { title: "Article 3", price: 1.49 },
  { title: "Article 1", price: 3.00 },
  { title: "Article 4", price: 5.99 },
  { title: "Article 2", price: 19.99 }
]

Basically I would like to push another article into the array at the correct position (by price). How can I do so?

The new article I'm pushing may have the following properties:

{ title: "Article 5", price: 12.00 }

I'm expecting the article to appear at index 3 (between article 4 and 2).

UPDATE (SOLUTION)

I created a prototype method using @klutt's answer with binary search algorithm:

Array.prototype.pushSorted = function(el, compareFn) {
  this.splice((function(arr) {
    var m = 0;
    var n = arr.length - 1;

    while(m <= n) {
      var k = (n + m) >> 1;
      var cmp = compareFn(el, arr[k]);

      if(cmp > 0) m = k + 1;
        else if(cmp < 0) n = k - 1;
        else return k;
    }

    return -m - 1;
  })(this), 0, el);

  return this.length;
};

const sortByPrice = (a, b) => a.price > b.price;
theArray.pushSorted({ title: "Article 5", price: 12.00 }, sortByPrice);
like image 464
Nordling Art Avatar asked Mar 22 '17 08:03

Nordling Art


People also ask

How do you push an element to an array at specific index?

You want to explicitly add it at a particular place of the array. That place is called the index. Array indexes start from 0 , so if you want to add the item first, you'll use index 0 , in the second place the index is 1 , and so on. To perform this operation you will use the splice() method of an array.

How do I push in a specific index?

In order to insert an element in the specific index, we need to provide the arguments as: start → the index in which to insert the element. deleteCount → 0 (because we don't need to delete any elements). elem → elements to insert.

How do you add to a sorted array?

To insert element in an array sorted in ascending order,First compare the elements which is to be inserted(num) with every elements of array from start, if num is greater than elements of array increament the position. And when the num become less than any element insert num to that position.

How do you push an object in an array at first position?

The unshift() method adds new elements to the beginning of an array. The unshift() method overwrites the original array.


1 Answers

The Update (Solution) still doesn't work great. Items that should go either to the start or end get placed in the wrong position, see this revised solution based on the same code:

Array.prototype.pushSorted = function(el, compareFn) {
  let index = (function(arr) {
    var m = 0;
    var n = arr.length - 1;

    while(m <= n) {
      var k = (n + m) >> 1;
      var cmp = compareFn(el, arr[k]);

      if(cmp > 0) m = k + 1;
        else if(cmp < 0) n = k - 1;
        else {
          console.log(`m=${m} k=${k}`)
          return k;
        };
    }


    return -m - 1;
  })(this);

  if (index >= 0)
    this.splice(index, 0, el);
  else if (index < 0)
    this.splice((index * -1) - 1, 0, el);

  return this.length;
};

Sample usage:

a = [1, 2, 3, 4, 5]
a.pushSorted(2.5, (a,b) => a - b);
a.pushSorted(8, (a,b) => a - b);
a.pushSorted(0.5, (a,b) => a - b);
like image 149
Pablote Avatar answered Oct 06 '22 00:10

Pablote