使用生成器作为多维数组替换



一段时间前,我构建了一个工具,一些人告诉我使用Generator而不是简单的数组,以获得更好的性能等。我开始使用Generator,然而,在谷歌上搜索Generator的问题是非常无用的,因为还没有太多关于Generator的信息。那么,让我们来谈谈我的问题

让我们想象一下下面的代码

$array  = [0, 1, 2, 3, 4, 5];
$mapper = ['zero', 'one', 'two', 'three', 'four', 'five'];
function mapNumbers($array, $mapper)
{
    foreach ($array as $element) {
        yield $element => $mapper[$element];
    }
}
foreach (mapNumbers($array, $mapper) as $key=>$value) {
    print $key . ' | ' . $value . '<br>';
}

这给出了以下输出

0 | zero
1 | one
2 | two
3 | three
4 | four
5 | five

然而,我现在想做的是一个多维数组。让我们想象一下下面的

$categories = ['food', 'nonfood'];
$products   = ['food' => ['meat', 'fish'], 'nonfood' => ['table', 'stool']];
function mapCategories($categories, $products)
{
    foreach ($categories as $category) {
        yield 'Category' => $category, 'Products' => $products[$category]
    }
}
foreach (mapCategories($categories, $products) as $key=>$value) {
    // do something
}

这当然不起作用,因为这条线给出了错误

yield 'Category' => $category, 'Products' => $products[$category]

我想用发电机做的事情可能吗?当我第一次学习生成器时,我认为生成器在某些情况下是用来替换数组的,但在试图构建多维数组时,它们似乎并没有替换数组。

这可能吗?如果是,如何?如果没有,我将如何将其与Generator结合起来?或者它要么只是生成器,要么只是数组?

非常感谢

虽然你可以使用生成器来实现你想要的:

$categories = ['food', 'nonfood'];
$products   = ['food' => ['meat', 'fish'], 'nonfood' => ['table', 'stool']];
function mapCategories($categories, $products) {
    foreach ($categories as $category) {
        yield ['Category' => $category, 'Products' => $products[ $category]];
    }
}
foreach (mapCategories($categories, $products) as $key=>$value) {
    echo $key, ' => '; var_dump($value); echo PHP_EOL;
}

除了代码的可读性之外,这样做并没有什么真正的好处。Generators的真正好处是,当您动态地主动检索/生成数据时,当您获得仅在实际需要时保存所需数据的内存优势时,以及当这样做可能更快时。简单地重新映射已经加载到PHP内存中的数据不会带来任何速度或内存优势。

在您的情况下,只需使用array_map()重新映射数据就可以提供所需的合并结构,同时仍然保持良好的可读性:

$categories = ['food', 'nonfood'];
$products   = ['food' => ['meat', 'fish'], 'nonfood' => ['table', 'stool']];
foreach (
    array_map(
        function ($value) use ($products) {
            return ['Category' => $value, 'Products' => $products[$value]];
        },
        $categories
    ) as $value) {
        var_dump($value);
}

我认为您想要的如下:

$categories = ['food', 'nonfood'];
$products   = ['food' => ['meat', 'fish'], 'nonfood' => ['table', 'stool']];
function mapCategories($categories, $products)
{
    foreach ($categories as $category) {
        foreach ($products as $product) {
            yield $category => $product;
        }
    }
}
# OR 
function mapCategories($categories, $products)
{
    foreach ($categories as $category) {
        yield $category => $products[$category];
    }
}

相关内容

  • 没有找到相关文章

最新更新