目录
- 前言
- 需求拆解
- 实现方法
- for循环实现
- 实现思路
- 代码实现
- 代码解析
- 示例输出
- slice实现
- 实现思路
- 代码实现:
- 代码解析
- 示例输出
- for循环实现
- 两种方法对比
- 总结
前言
你好,我是喵喵侠。今天我收到了一个需求,有一个视频列表,页面上显示的布局是2x2,但后端返回的视频列表数据通常是大于4个的。也就是说,假设后端返回5条数据,默认先展示前4条,后面每隔固定时间(比方说10秒),切换下一组数据显示。如果超出边界,则索引从前面开始取值。这样描述可能不是特别清晰,下面我把需求进行举例拆解,一看就明白了。
需求拆解
假设有一个数组是[1,2,3,4,5,6,7,8,9]
,数组长度是9,每次都是截取4个元素,开始索引每次截取完成后会 4。具体的截取结果示例如下:
- 第1次截取:[1,2,3,4]
- 第2次截取:[5,6,7,8]
- 第3次截取:[9,1,2,3]
- 第4次截取:[4,5,6,7]
- 第5次截取:[8,9,1,2]
- ……
这样看就很清晰了,如果截取到后面数组元素不够了,就从前面取,保证一次取完4个就可以了,无限循环。
实现方法
for循环实现
你想要从一个数组中每隔10秒钟截取4个元素,并且索引循环滚动。例如,数组长度为9时,第一次取前4个,第二次从第5个开始取,之后再循环到开头。你可以通过以下方式实现这个需求:
实现思路
- 每次截取4个元素:可以使用
Array.prototype.slice()
来获取数组的子集。 - 滚动索引:利用模运算来实现索引的循环滚动(防止数组越界)。
- 定时器:使用
setInterval
每隔10秒执行一次截取操作。
代码实现
代码语言:javascript复制const arr = [
{ name: 'A', url: 'url1' },
{ name: 'B', url: 'url2' },
{ name: 'C', url: 'url3' },
{ name: 'D', url: 'url4' },
{ name: 'E', url: 'url5' },
{ name: 'F', url: 'url6' },
{ name: 'G', url: 'url7' },
{ name: 'H', url: 'url8' },
{ name: 'I', url: 'url9' }
];
let startIndex = 0;
const interval = 10 * 1000; // 每隔10秒,这里用乘法,方便修改时间
function getNextFourElements(arr, startIndex) {
const result = [];
const len = arr.length;
for (let i = 0; i < 4; i ) {
const index = (startIndex i) % len; // 模运算实现索引滚动
result.push(arr[index]);
}
return result;
}
// 定时器每隔10秒调用一次
setInterval(() => {
const fourElements = getNextFourElements(arr, startIndex);
console.log(fourElements); // 输出当前4个元素
startIndex = (startIndex 4) % arr.length; // 更新起始索引,滚动到下一个位置
}, interval);
代码解析
getNextFourElements
函数用于获取从startIndex
开始的4个元素。通过(startIndex i) % len
实现数组的索引滚动。- 每次定时器触发时,
startIndex
会更新为下一个位置的起点,继续截取4个元素。 - 通过
setInterval
实现每隔10秒输出结果。
示例输出
假设数组长度为9,输出会是这样的:
- 第一次:
A, B, C, D
- 第二次:
E, F, G, H
- 第三次:
I, A, B, C
- 第四次:
D, E, F, G
- 第五次:
H, I, A, B
这个方案保证了每次从数组中滚动截取4个元素,无论数组长度是多少,都能循环输出。
slice实现
使用 slice
来实现你的需求,同时考虑边界问题,可以通过判断 startIndex
和数组长度来处理数组的循环切片。以下是基于 slice
的实现:
实现思路
slice
** 切割数组**:如果startIndex 4
超过数组长度时,需要从数组头部补足剩余的元素。- 边界处理:通过判断
startIndex 4
是否超过数组长度,来决定是否需要从头开始截取。
代码实现:
代码语言:javascript复制const arr = [
{ name: 'A', url: 'url1' },
{ name: 'B', url: 'url2' },
{ name: 'C', url: 'url3' },
{ name: 'D', url: 'url4' },
{ name: 'E', url: 'url5' },
{ name: 'F', url: 'url6' },
{ name: 'G', url: 'url7' },
{ name: 'H', url: 'url8' },
{ name: 'I', url: 'url9' }
];
let startIndex = 0;
const interval = 10 * 1000; // 每隔10秒
function getNextFourElements(arr, startIndex) {
const len = arr.length;
let result = [];
if (startIndex 4 <= len) {
// 如果从 startIndex 开始截取4个元素不会越界
result = arr.slice(startIndex, startIndex 4);
} else {
// 如果越界了,需要从头开始补齐
const firstPart = arr.slice(startIndex, len); // 从 startIndex 到数组末尾
const secondPart = arr.slice(0, (startIndex 4) % len); // 从数组开头补齐
result = firstPart.concat(secondPart);
}
return result;
}
// 定时器每隔3秒调用一次
setInterval(() => {
const fourElements = getNextFourElements(arr, startIndex);
console.log(fourElements); // 输出当前4个元素
startIndex = (startIndex 4) % arr.length; // 更新起始索引,循环滚动
}, interval);
代码解析
- 切割逻辑:
- 如果
startIndex 4
不超过数组长度,则直接用slice
截取从startIndex
开始的4个元素。 - 如果
startIndex 4
超过数组长度,则通过两次slice
操作:第一次从startIndex
到数组末尾,第二次从数组头部截取剩下的元素。
- 如果
- 索引更新:每次更新
startIndex
时,使用模运算startIndex = (startIndex 4) % arr.length
保证它在数组长度内循环。
示例输出
假设数组长度为9,输出会是这样的:
- 第一次:
A, B, C, D
- 第二次:
E, F, G, H
- 第三次:
I, A, B, C
- 第四次:
D, E, F, G
- 第五次:
H, I, A, B
这个实现基于 slice
方法,确保了每次从数组中正确地滚动截取4个元素,无论数组长度是多少,都能循环滚动。
两种方法对比
这里我简单画一个表格,来从代码简洁性、可读性、执行效率三个角度来看,哪种方法更优。
方法 | 代码简洁性 | 可读性 | 执行效率 |
---|---|---|---|
for循环 | 起始索引递增取余数组长度十分巧妙,不需要关心是否越界,代码量更少 | 可读性略差,需要理解每一项循环取余的操作。 | 理论上每次执行只访问4次数组元素,数据量大执行效率会更高 |
slice方法 | 需要关心是否越界,需要手动拼接处理,代码较为冗余。 | 数组自带方法,逻辑更清晰,代码更简洁。 | slice会返回新数组,可能会有额外开销 |
综上所述,我个人觉得for的方式更为巧妙,执行效率更高,以后可以采用这种方式。如果你对slice数组方法比较熟悉,数据量不大的情况下,用这种方式实现,可读性会更好,更容易让人明白意图。
总结
通过这个实际需求,相信你学会了如何用JavaScript循环截取指定长度的数组,一开始看代码理解会有点点绕,多看几遍就好了。希望你可以把这个技巧用到你的工作中去,后面我会分享更多JavaScript实际案例技巧。