003 %取模运算符的妙用

121 阅读3分钟

学习Vue3条件渲染的时候看到这个一个例子:

<script setup>
import { ref, computed } from "vue";
const TRAFFIC_LIGHTS = ["红灯", "黄灯", "绿灯"];
const lightIndex = ref(0);

const light = computed(() => TRAFFIC_LIGHTS[lightIndex.value]);

function nextLight() {
  lightIndex.value = (lightIndex.value + 1) % TRAFFIC_LIGHTS.length;
}
</script>

<template>
  <button @click="nextLight">
    下一个灯
  </button>
  <p>现在亮着的是: {{ light }}</p>
  <p>
    你应该
    <span v-if="light === '红灯'">停下</span>
    <span v-else-if="light === '黄灯'">慢行</span>
    <span v-else-if="light === '绿灯'">赶紧走</span>
  </p>
</template>

例子内容很简单,一个使用红绿灯的变化体现条件渲染的逻辑,可是其中的一行代码一下没太明白,即:

lightIndex.value = (lightIndex.value + 1) % TRAFFIC_LIGHTS.length;

按照本人以往的编码想法,切换索引的逻辑会是如下的,当然也是可以实现同样的结果:

lightIndex.value = (lightIndex.value + 1) === TRAFFIC_LIGHTS.length ? 0 : (lightIndex.value + 1);

看到看不明白的代码中用到了%,这是怎么回事呢?

回答自ChatGPT-4

console.log(1 % 3);为例:

这段代码是在JavaScript中使用取模运算符 %。让我为您详细解释:

  1. 运算符解释: % 是取模(也称为取余)运算符。它返回除法运算后的余数。

  2. 运算过程:

    • 1 除以 3 的商是 0
    • 余数是 1
  3. 结果: 这行代码会在控制台输出 1

  4. 更多解释:

    • 当被除数小于除数时,结果就是被除数本身
    • 在这个例子中,1 小于 3,所以结果就是 1
  5. 实际应用: 取模运算常用于:

    • 判断奇偶数(如 n % 2 === 0 判断偶数)
    • 循环数组索引(如 index % array.length)
    • 周期性的计算等

这个简单的操作展示了 JavaScript 中基本的算术运算符的使用。理解这些基础运算对于编程非常重要。


通过上面的回答可以看到本文开头的示例的使用是用到了%循环数组索引的用法,那么更多的该用法解释是什么呢?

回答自ChatGPT-4

取模运算确实是一种常用于循环数组索引的有效方法。这种技术通常被称为"循环数组"或"环形缓冲区"。让我为您详细解释一下这个概念及其实现。

  1. 基本原理

取模运算(%)可以将一个数限制在一个固定的范围内。对于数组来说,这个范围就是从0到数组长度减1。

  1. 实现方法

假设我们有一个长度为n的数组,当索引i超过数组长度时,我们可以使用 i % n 来获得有效的数组索引。

  1. 代码示例

下面是一个TypeScript实现的例子:

/**
 * 循环访问数组元素
 * @param arr 要循环的数组
 * @param startIndex 开始索引
 * @param count 要访问的元素数量
 */
function cycleArray<T>(arr: T[], startIndex: number, count: number): T[] {
    const result: T[] = [];
    const n = arr.length;
    
    for (let i = 0; i < count; i++) {
        // 使用取模运算循环索引
        const index = (startIndex + i) % n;
        result.push(arr[index]);
    }
    
    return result;
}

// 使用示例
const arr = [1, 2, 3, 4, 5];
console.log(cycleArray(arr, 3, 7)); // 输出: [4, 5, 1, 2, 3, 4, 5]
  1. 优势

    • 简洁高效:无需额外的条件判断,直接用一个表达式就能处理索引循环。
    • 灵活:可以从任意位置开始,向前或向后循环任意次数。
    • 内存效率:不需要创建新的数组,直接在原数组上操作。
  2. 应用场景

    • 循环播放列表
    • 环形缓冲区实现
    • 周期性的数据处理
    • 图形旋转(如时钟指针)
  3. 注意事项

    • 确保用于取模的数(数组长度)为正数。
    • 对于负数索引,可能需要额外处理:(i % n + n) % n

取模运算在循环数组索引中的应用非常广泛,它提供了一种简单而有效的方法来处理需要循环访问的数据结构。