Получить окно позиций вокруг центральной точки js

Я пытаюсь понять, как получить окно позиций, основанное на центральной точке в JavaScript.

Скажем, у меня есть следующий массив: [0,1,2,3,4,5,6,7,8,9]

Если бы я хотел получить позицию 5 в качестве центральной точки, я также хотел бы получить позиции 3,4,6 и 7, которые давали бы [3,4,5,6,7].

Тем не менее, я также пытаюсь получить его, когда он находится в пределах досягаемости левой или правой границы массива, он толкает окно в противоположном направлении. Например, если бы мне нужна позиция 1, я бы хотел, чтобы массив возвращался как [0,1,2,3,4]. Или, если мне нужна позиция 0, мне нужен массив как [0,1,2,3,4]. То же самое относится и к концу массива, например. Я хочу получить позицию 8, чтобы вернуться [5,6,7,8,9].

Я изо всех сил пытаюсь получить это в JavaScript, и я чувствую, что слишком усложняю вопрос. Мой текущий код выглядит следующим образом, однако я вообще не привязан к этому коду, поэтому полностью изменить его можно:

positions() {
    let left = 0;
    let right = 5;
    let middle = this.steps.length / 2;
    // Closer to left.
    if (this.index < middle) {
        if (this.steps[this.index - 2]) {
            left = this.index - 2;
            right = this.index + 2;
        }
        else if (this.steps[this.index - 1]) {
            left = this.index - 1;
            right = this.index + 3;
        }
    }
    // Closer to right.
    else if (this.index > middle) {
        if (this.steps[this.index + 3]) {
            left = this.index - 2;
            right = this.index + 3;
        }
        else if (this.steps[this.index + 2]) {
            left = this.index - 3;
            right = this.index + 2;
        }
        else if (this.steps[this.index + 1]) {
            left = this.index - 4;
            right = this.index + 1;
        }
    }
    else {
        left = this.index - 2;
        right = this.index + 3;
    }
    return { left, right };
},
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
70
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

var steps = [0,1,2,3,4,5,6,7,8,9];
var res = [];
var i = 3; // index // or 0, 9, 8, 2, 1
var mid = steps.length / 2;

var lenghOfResult = 5;

var left = 0;
var right = 0;

function computed() {
   res = [];
   res.push(i);

   left = i;
   right = i;
   
   for(let c=1;c<=lenghOfResult;c++) { 
      if (steps.hasOwnProperty(i-c) && (i-c <= i-1) && res.length <lenghOfResult) 
      {
        left = i-c;
        res.unshift((i-c));
      }
     if (steps.hasOwnProperty(i+c) && (i+c >= i)  && res.length <lenghOfResult) {
       right = i+c;
       res.push((i+c));
     }
   }
   
   console.info('left', left, 'right', right);
}

computed();

console.info(res);

let array = [0,1,2,3,4,5,6,7,8,9]
const getSlice = (arr,index) => {
    let leftSide = index  - 2;
    let rightSide = index + 2;
    if (leftSide<0){
        return arr.slice(0,5)
    }
    if (rightSide >= arr.length){
        return arr.slice(arr.length-5)
    }
    return arr.slice(index-2,index+3)
}

console.info(getSlice(array,0))
console.info(getSlice(array,1))
console.info(getSlice(array,2))
console.info(getSlice(array,4))
console.info(getSlice(array,7))
console.info(getSlice(array,8))
console.info(getSlice(array,9))
Ответ принят как подходящий

Вы можете использовать некоторые математические расчеты, чтобы рассчитать, что вы получаете.

  1. Начальный индекс — это центральная точка минус желаемый диапазон. Например, центр 5 и диапазон 2 дают начальную позицию 5 - 2 = 3.
  2. Конечный индекс - это центральная точка плюс пролет. Например, центр 5 и диапазон 2 дают конечную позицию 5 + 2 = 7.
[0,1,2,3,4,5,6,7,8,9]
       ^   ^   ^
       |   |   |
start -+   |   |
centre +---+   |
end ---+-------+
       |       |
      [3,4,5,6,7]

Чтобы справиться с «переполнением», вы можете зафиксировать начальное/конечное значение.

  • start не может быть ниже начала массива (то есть 0).
  • в то время как end может быть не более чем последней позицией массива (это arr.length - 1).

Если начальная или конечная позиция образует меньший промежуток, чем ожидаемый, остаток может быть перенесен на противоположный индекс:

С центром 1 и размахом 2:

       [0,1,2,3,4,5,6,7,8,9]
        ^ ^     ^
        | |     |
start --+ |     |
centre ---+     |
padded end -----+

С центром 8 и размахом 2:

       [0,1,2,3,4,5,6,7,8,9]
                  ^     ^ ^
                  |     | |
padded start -----+     | |
centre -----------------+ |
end ----------------------+

Наконец, осталась единственная ситуация, которую нужно решить, — это то, что произойдет, если массив просто недостаточно велик. Это зависит от вас, просто возврат всего массива имеет смысл, но вы также можете выбрать ошибку или пустой массив. Если вы уверены, что этого никогда не произойдет, вы также можете оставить это без внимания.

Вот как может выглядеть реализация

function getRange(arr, pos, span) {
  if ((span*2 + 1) > arr.length) {
    throw Error("not enough items in array"); //or just return arr; or return []; etc.
  }
  
  let start = Math.max((pos - span), 0);
  let end = Math.min((pos + span), arr.length - 1);
  
  const leftoverStart  = span - (pos - start);
  const leftoverEnd    = span - (end - pos);
  
  if (leftoverStart) {
    end += leftoverStart;
  } else if (leftoverEnd) {
    start -= leftoverEnd;
  }
  
  return arr.slice(start, end+1);
}

const arr = [0,1,2,3,4,5,6,7,8,9];

console.info(getRange(arr, 5, 2));
console.info(getRange(arr, 1, 2));
console.info(getRange(arr, 8, 2));

Другие вопросы по теме