如何用模运算(%)简化索引分组条件判断

本文介绍如何使用取模运算符 `%` 替代冗长的硬编码索引列表,简洁高效地实现按周期(如每10个索引一组)执行不同逻辑的条件分支。

在 Blade 模板或 PHP 逻辑中,当需要根据循环索引 index 执行分组操作(例如:索引 0、10、20、30… 执行 A 操作;1、11、21、31… 执行 B 操作;以此类推),直接罗列所有可能值(如 $loop->index == 0 || $loop->index == 10 || ...)不仅代码臃肿、难以维护,还存在可读性差和易出错等问题。

核心思路是利用模运算(%)提取索引的“周期内偏移量”
对任意非负整数 n,n % 10 的结果恒为 0 到 9 之间的余数,恰好对应其在每 10 个元素为一组的循环中的位置。例如:

  • 0 % 10 = 0, 10 % 10 = 0, 20 % 10 = 0 → 归为第 0 组
  • 1 % 10 = 1, 11 % 10 = 1, 21 % 10 = 1 → 归为第 1 组
  • 9 % 10 = 9, 19 % 10 = 9, 99 % 10 = 9 → 归为第 9 组

因此,只需一次取模运算,即可将无限延伸的索引序列映射到有限的 0–9 分组中。

✅ 推荐写法:使用 @switch(Blade 中最清晰)

@switch($loop->index % 10)
    @case(0)
        {{-- 索引为 0, 10, 20, 30, ... --}}
        Header Section
        @break

    @case(1)
        {{-- 索引为 1, 11, 21, 31, ... --}}
        Subheader Section
        @break

    @case(2)
        {{-- 索引为 2, 12, 22, 32, ... --}}
        Feature Card
        @break

    @case(9)
        {{-- 索引为 9, 19, 29, 39, ... --}}
        Footer Banner
        @break

    @default
        {{-- 其他情况(理论上不会发生,因 % 10 结果必为 0–9) --}}
        Default Layout
@endswitch

✅ 替代写法:精简 @if 链(兼容性更强)

@if ($loop->index % 10 === 0)
    {{-- Group 0 --}}
@elseif ($loop->index % 10 === 1)
    {{-- Group 1 --}}
@elseif ($loop->index % 10 === 2)
    {{-- Group 2 --}}
@elseif ($loop->index % 10 === 9)
    {{-- Group 9 --}}
@endif
? 提示:使用严格比较 === 可避免类型隐式转换带来的意外行为(如 0 == '0' 为 true,但 0 === '0' 为 false)。

⚠️ 注意事项与最佳实践

  • 索引范围假设:本方案默认 $loop->index 是从 0 开始的非负整数(Laravel 的 @foreach $loop->index 正是如此)。若索引可能为负数或非整数,请先校验或转换。
  • 性能无负担:% 是底层快速运算,远优于多次 == 判断,且随索引增长零开销。
  • 可扩展性强:若需改为每 5 个一组,只需将 10 替换为 5;每 100 个一组则用 100 —— 逻辑完全不变。
  • 避免魔法数字:在复杂项目中,建议将周期值定义为常量或变量,提升可维护性:
    @php($groupSize = 10)
    @switch($loop->index % $groupSize)
        @case(0) ... @break
        @case(1) ... @break
    @endswitch

通过模运算重构条件逻辑,你不仅让代码更短、更健壮,也体现了对数学规律的合理运用——这是编写可维护、可扩展模板的关键一步。