Я пытаюсь понять, как получить окно позиций, основанное на центральной точке в 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 };
},
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))
Вы можете использовать некоторые математические расчеты, чтобы рассчитать, что вы получаете.
5
и диапазон 2
дают начальную позицию 5 - 2 = 3
.5
и диапазон 2
дают конечную позицию 5 + 2 = 7
.[0,1,2,3,4,5,6,7,8,9]
^ ^ ^
| | |
start -+ | |
centre +---+ |
end ---+-------+
| |
[3,4,5,6,7]
Чтобы справиться с «переполнением», вы можете зафиксировать начальное/конечное значение.
0
).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));