best/fastest 做法是什么?在 switch 语句的每个 case 中创建相同的循环,或者切换 for 循环的相同 case?

Which is the best/fastest practice? Create the same loop in each case of a switch statement, or to switch the same case of a for loop?

所以我正准备写类似下面的代码

switch ($mode) {
    case 'all':
        foreach ($sortInfo as $info) $filter[] = array_merge([$info->maincat], $info->subcats);
        break;
    case 'sub':
        foreach ($sortInfo as $info) $filter[] = $info->subcats;
        break;
    default:
        foreach ($sortInfo as $info) $filter[] = [$info->maincat];
        break;
}

然后我告诉自己“嘿,如果我把整个 switch 包装在 for 循环中不是更优化吗?”

foreach ($sortInfo as $info) {
    switch ($mode) {
        case 'all':
            $filter[] = array_merge([$info->maincat], $info->subcats);
            break;
        case 'sub':
            $filter[] = $info->subcats;
            break;
        default:
            $filter[] = [$info->maincat];
            break;
    }
}

但是虽然它在技术上确实节省了一点 (明白了吗?) 文件大小,但循环会在循环的每次迭代中确认 switch 语句中的相同信息。

我认为没有 objective 方法可以确定哪个最快,因为它取决于 $sortinfo 的长度,但由于这是我第一次遇到这种困境,我想了解是否有首选方法,或者您对此有何看法。

基本上,代码和结果是一样的,但我认为第一个会更快,因为它更简单而且 straight-forward。第二个看起来更干净,但它需要 switch-case 并在每次循环时做出决定,这会减慢整个过程。

由于您只会 运行这一次,因此任何性能差异都可以忽略不计。如果必须 运行 数千次,您可以使用固定数据集进行基准测试,但我仍然怀疑您是否会看到超过 +/- 10% 的差异。选择您认为更具可读性的版本。如果你想节省位并且运行宁PHP 8,你可以这样做:

$cats = match($mode) {
    'all' => array_merge(
        array_column($sortInfo, 'maincat'), ...array_column($sortInfo, 'subcats')
    ),
    'sub' => array_merge(...array_column($sortInfo, 'subcats')),
    default => array_column($sortInfo, 'maincat')
};

更新: 根据 OP 的修订,maincat 是单个标量,subcats 是标量数组。由于我们希望在所有模式下都有一个一维数组,因此我们使用 ... to "dish out" the subcategories into the array_merge, which gives us a "flat" array. Demo: 3v4l.org/NasiC

这是 227 位与“foreach 切换”中的 338 位对比“foreach 切换”中的 346 位或减少 33%。我发现这种方法 非常 可读并且没有可避免的冗长。

如果你还在 运行nning PHP 7,你可以把这个方法考虑到一个转换中:

switch ($mode) {
    case 'all': 
        $cats = array_merge(
            array_column($sortInfo, 'maincat'), ...array_column($sortInfo, 'subcats')
        );
    break;
    case 'sub': 
        $cats = array_merge(...array_column($sortInfo, 'subcats'));
        break;
    default: 
        $cats = array_column($sortInfo, 'maincat');
        break;
};

仍然只有 299 个字节。 :) N.B。 match 是我提早升级到 PHP 的主要原因之一 8. 一些菜肴的高级糖,消除了很多样板代码。

好的,看起来提问者不会响应我对示例数据和预期结果的请求。

为了尽量减少重复条件的数量,您可以确定模式是否为“sub”,并简单地收集该列数据(无需任何复杂的处理)。

否则,已知结果中将需要“maincat”数据。唯一要确定的是“subcats”是否应该被推入结果(每行——否则“maincat”和“subcats”关系将被破坏)。

这是直接和简洁的,但它不像 switch()match() 块那样享有最佳的可维护性。如果您不希望扩展代码段的功能,我会在循环前使用一个条件,在循环内使用一个条件。

代码:(没有演示,因为没有提供示例数据)

if ($mode === 'sub') {
    $filter = array_column($sortInfo, 'subcats');
} else {
    $filter = [];
    foreach ($sortInfo as $info) {
        $filter[] = [$info->maincat, ...($mode === 'all' ? $info->subcats : [])];
    }
}