How to keep Javascript array sorted, without sorting it

后端 未结 3 1847
暖寄归人
暖寄归人 2021-02-04 17:25

I have a Node.js application where I have to very often do following things: - check if particular array already contains certain element - if element does exist, update it - if

相关标签:
3条回答
  • 2021-02-04 18:04

    If your array is already sorted and you want to insert an element, to keep it sorted you need to insert it at a specific place in the array. Luckily arrays have a method that can do that: Array.prototype.splice

    So, once you get the index you need to insert at (you should get by a simple modification to your binary search), you can do:

    myArr.splice(myIndex,0,myObj);
    // myArr your sorted array
    // myIndex the index of the first item larger than the one you want to insert
    // myObj the item you want to insert
    

    EDIT: The author of your binary search code has the same idea:

    So if you wanted to insert a value and wanted to know where you should put it, you could run the function and use the returned number to splice the value into the array. Source

    0 讨论(0)
  • 2021-02-04 18:07

    It's easy to modify this binaryIndexOf function to return an index of the next element when no matches found:

    function binaryFind(searchElement) {
      'use strict';
    
      var minIndex = 0;
      var maxIndex = this.length - 1;
      var currentIndex;
      var currentElement;
    
      while (minIndex <= maxIndex) {
        currentIndex = (minIndex + maxIndex) / 2 | 0;
        currentElement = this[currentIndex];
    
        if (currentElement < searchElement) {
          minIndex = currentIndex + 1;
        }
        else if (currentElement > searchElement) {
          maxIndex = currentIndex - 1;
        }
        else {
          return { // Modification
            found: true,
            index: currentIndex
          };
        }
      }      
    
      return { // Modification
        found: false,
        index: currentElement < searchElement ? currentIndex + 1 : currentIndex
      };
    }
    

    So, now it returns objects like:

    {found: false, index: 4}
    

    where index is an index of the found element, or the next one.

    So, now insertion of a new element will look like:

    var res = binaryFind.call(arr, element);
    if (!res.found) arr.splice(res.index, 0, element);
    

    Now you may add binaryFind to Array.prototype along with some helper for adding new elements:

    Array.prototype.binaryFind = binaryFind;
    
    Array.prototype.addSorted = function(element) {
      var res = this.binaryFind(element);
      if (!res.found) this.splice(res.index, 0, element);
    }
    
    0 讨论(0)
  • 2021-02-04 18:11

    I know this is an answer to an old question, but the following is very simple using javascripts array.splice().

    function inOrder(arr, item) {
        /* Insert item into arr keeping low to high order */
    
        let ix = 0;
        while (ix < arr.length) {
            //console.log('ix',ix);
            if (item < arr[ix]) { break; }
            ix++;
        }
    
        //console.log('  insert:', item, 'at:',ix);
        arr.splice(ix,0,item);
        return arr
    }
    

    The order can be changed to high to low by inverting the test

    0 讨论(0)
提交回复
热议问题