Javascript 在数组中向前和向后选择X数量,如果需要,循环到开始和结束
我需要,给定一个数组索引和一个范围,在返回新索引的数组中向前循环X amount,向后循环X amount 如果循环向前到达数组的末尾,它将在数组的开头继续。如果循环在返回时到达起始点,则在数组的末尾继续 例如,对于阵列:Javascript 在数组中向前和向后选择X数量,如果需要,循环到开始和结束,javascript,arrays,math,filter,Javascript,Arrays,Math,Filter,我需要,给定一个数组索引和一个范围,在返回新索引的数组中向前循环X amount,向后循环X amount 如果循环向前到达数组的末尾,它将在数组的开头继续。如果循环在返回时到达起始点,则在数组的末尾继续 例如,对于阵列: [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] 我试图写一个解决方案,但它只适用于固定范围的数字,而且非常粗糙。只是
[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解决方案,但如果需要,我很乐意从另一种语言翻译逻辑
谢谢。功能转盘(数组,索引,n){
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));
var结果=[];
对于(var i=索引-n,len=array.length;i len-1?i-len:i]);
}
返回结果;
}
//试验
变量数组=[0,1,2,3,4,5,6,7,8,9],
指数=8,
n=3;
日志(旋转木马(数组,索引,n));
演示:使用模数这非常简单:
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);
var数组=[0,1,2,3,4,5,6,7,8,9],
指数=8,
n=3;
var结果=[];
对于(var i=index-n,len=array.length;i=len
。您可以将此视为在实际数组的左侧和右侧都有无限次的数组重复。如果i<0
,我们将访问左侧的一个虚拟数组,如果i>=len
,我们将访问右侧的一个虚拟数组。索引转换为格式化(i+len)%len
然后处理将“虚拟”索引转换回实际数组索引的过程
有两个边界条件和访问“正常”索引的情况:
<代码> < < 0 < /代码>:考虑例如“代码> i= -3 < /P>
(i+len)
会将位置移动一个完整的数组,以便我们在虚拟数组中向右工作,但指向同一个元素。模数没有影响,因为len-3
小于len
<代码> i>=Le< <代码>:考虑例如<代码> I= LEN + 4
(i+len)
会将一个数组的位置向右移动。在我们的示例中,(i+len)
将是(len+4+len)
,但模抵消了这些移位,因此我们得到4
c) i
是原始数组中的有效索引
(i+len)
会将一个数组的位置向右移动,但这是由模数重置的,因为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));
函数转盘(数组,任意索引,n){
var结果=[];
索引=任意索引%(数组长度);
对于(var i=索引-n,len=array.length;i len-1?i-len:i]);
}
返回结果;
}
变量数组=[0,1,2,3,4,5],
任意指数=-12,
n=3;
log(carousel(数组,任意索引,n));
完全按照预期工作!我还喜欢,如果范围导致重叠,它就不会崩溃,因为之后很容易从返回的数组中删除重复项(例如,n=7)。我花了几秒钟才意识到双重速记if语句到底是怎么回事。该死的,我在写,你写得更快……尽管你可能需要小心。@Kayo我个人喜欢这种方式。使用模运算符也是一种很短很好的方法。@Passenger:太棒了!我认为解决这个问题的方法是添加一些类似n的东西,非常好。在这种情况下,模是如何工作的?我以前用过它,比如用if(I%2==0)替换类名之类的。我尝试了一个解释来更新它。非常感谢你的解释。我把你的答案移到了可接受的答案上,主要是因为VisioN的答案会在你在评论中提到的溢出时导致未定义的出现,尽管这两个答案都是解决问题的好例子。