How to sort only part of array? between given indexes

天涯浪子 提交于 2021-01-28 19:46:37

问题


I have an array of numbers and I need to sort only part of it by left and right barriers. Can you please help me how to implement it correctly?

const sortBetween = (arr, left, right) => {
   ...
}
given: [9,3,5,7,4,9,4,1] , left = 2, right = 5
expected: [9,3,4,5,7,9,4,1]

[9,3,5,7,4,9,4,1] -> [9,3,4,5,7,9,4,1]

Thanks for the help.


回答1:


This is an approach by using sort directly, but shaping the access with a Proxy for length and the indices.

  type        original array       length
-------  ------------------------  ------
values    9  3  5  7  4  9  4  1       8
indices   0  1  2  3  4  5  6  7
-------  ------------------------  ------

  type          proxy view         length
-------  ------------------------  ------
values          5  7  4  9             4
indices         0  1  2  3
-------  ------------------------  ------

const
    sortBetween = (array, left, right) => {
        new Proxy(array, {
            get (target, prop) {
                if (isFinite(prop)) return target[+prop + left];
                if (prop === 'length') return right - left + 1;
                return target[prop];
            },
            set (target, prop, receiver) {
                target[+prop + left] = receiver;
                return true;
            }
        })
        .sort((a, b) => a - b);

        return array;
    };    
    
console.log(...sortBetween([9, 3, 5, 7, 0, 9, 4, 1], 2, 5)); // [9, 3, 0, 5, 7, 9, 4, 1]



回答2:


You can do it by using the Divide and Conquer method. You can try this-

const sortBetween = (arr, left, right) => {
  let leftArr = [],
    rightArr = [],
    sortedArr = [];
    
  /**
   * Divide the array into 3 parts. Left, Mid, Right.
   * You have to sort the mid one.
   */
  
  if (left > 0) {
     leftArr = arr.slice(0, left);
  }
  
  if (right < arr.length) {
    rightArr = arr.slice(right);
  }
  
  sortedArr = arr.slice(left, right).sort();
  
  // Finally merge the 3 parts and returns
  return [...leftArr, ...sortedArr, ...rightArr];
}

const arr = [9,3,5,7,4,9,4,1];

const res = sortBetween(arr, 2, 5);
const res1 = sortBetween(arr, 0, 5);
const res2 = sortBetween(arr, 0, 8);

console.log(res, res1, res2);
.as-console-wrapper {min-height: 100%!important; top: 0}



回答3:


Final (I hope):

newArr = [].concat(
  arr.slice(0,left),
  arr.slice(left,right+1).sort(),
  arr.slice(right+1,arr.length)
)

taking right inclusively,
assuming left is not greater than right,
assuming the array is not empty,
etc.


Previous Edit:
I've read the comments.
Mostly correct.
The problem I oversaw was that the sort requested is between left and right inclusively, whereas slice's first argument is inclusive and second argument is exclusive.

I see, now, the last part should be an negative value, the difference between left and the array's length.
But, I'm not going to try to resolve that...

My original "answer":
I suggest you split the array into 3 sub-arrays using slice, sort the middle, and then put them back together using concat, such as so:

newArr=[].concat(arr.slice(0,left),arr.slice(left,right+1).sort(),arr.slice(left+right-1))

May I suggest you get more familiar with slice and concat by searching the web?



来源:https://stackoverflow.com/questions/62849907/how-to-sort-only-part-of-array-between-given-indexes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!