2

我需要,给定一个数组索引和一个范围,在返回新索引的数组中循环向前 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 解决方案,但如果需要,我很乐意从另一种语言翻译逻辑。

谢谢你。

4

3 回答 3

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.

于 2013-10-14T11:00:52.880 回答
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));

演示:http: //jsfiddle.net/SUGhf/

于 2013-10-14T10:57:19.533 回答
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));
于 2013-12-30T19:29:16.560 回答