我需要,给定一个数组索引和一个范围,循环在数组中转发X量和向后X量返回新索引。
如果循环到达数组的结尾,它将继续在数组的开头。如果循环在向后移动时到达开头,它将继续在数组的末尾。
例如,使用数组:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
如果索引为8,范围为3,则函数将返回[5, 6, 7 ,8, 9, 0, 1]
或者,如果索引为1,范围为3,则返回[8,9,0,1,2,3,4]
我尝试过写一个解决方案,但它只适用于固定范围的数字而且非常粗糙。只是想知道是否有一种简洁的方法来实现这一目标。 Javascript解决方案更受欢迎,但如果需要,我很乐意将逻辑转换为另一种语言。
谢谢。
答案 0 :(得分:2)
使用模数非常简单:
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
index = 8,
n = 3;
var result = [];
for (var i = index - n, len = array.length; i <= index + n; i++) {
result.push(array[(i + len) % len]);
}
console.log(result);
编辑JSFiddle:http://jsfiddle.net/cmymS/
本例中对模运算符的解释:
模运算符处理越过边界。在for循环内部,i
是数组中的“虚拟”索引,可以小于0或>= len
。您可以将此视为在实际数组的左侧和右侧都有无限重复的数组。如果i < 0
,我们正在访问左侧的一个虚拟阵列,如果i >= len
,我们将访问右侧的一个虚拟阵列。然后,索引转换(i + len) % len
处理将“虚拟”索引转换回实际的数组索引。
有两种边界条件和访问“正常”索引的情况:
a)i < 0
:考虑例如i = -3
。
(i + len)
会将位置移动一整个数组,以便我们在虚拟数组中向右工作,但指向相同的元素。由于len - 3
小于len
,因此模数无效。
b)i >= len
:考虑例如i = len + 4
(i + len)
会将位置向右移动一个数组。在我们的示例中,(i + len)
将为(len + 4 + len)
,但模数会中和这些变化,因此我们得到4
。
c)i
是原始数组中的有效索引
(i + len)
会将位置向右移动一个数组,但这会由0 <= i < len
以来的模数重置。 (i + len) % len = i
。
答案 1 :(得分:1)
function carousel(array, index, n) {
var result = [];
for (var i = index - n, len = array.length; i <= index + n; i++) {
result.push(array[i < 0 ? len + i : i > len - 1 ? i - len : i]);
}
return result;
}
// TEST
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
index = 8,
n = 3;
console.log(carousel(array, index, n));
答案 2 :(得分:0)
我正在寻找能给我同样东西的东西,但不仅仅是使用数组中的索引,而且可以使用无限的任意位置(即+100 - 100),所以我在上面的代码中添加了一行代码-12。如果有人需要它。
function carousel(array, arbitraryIndex, n) {
var result = [];
index = arbitraryIndex % (array.length);
for (var i = index - n, len = array.length; i <= index + n; i++) {
result.push(array[i < 0 ? len + i : i > len - 1 ? i - len : i]);
}
return result;
}
var array = [0, 1, 2, 3, 4, 5],
arbitraryIndex = -12,
n = 3;
console.log(carousel(array, arbitraryIndex, n));