【发布时间】:2015-09-17 01:28:41
【问题描述】:
前段时间我构建了一个工具,有人告诉我使用生成器而不是简单的数组来获得更好的性能等。我开始使用生成器,但是,谷歌搜索生成器的问题是非常无用的,因为没有发电机的很多信息。那么,让我们来回答我的问题
让我们想象下面的代码
$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]
我正在尝试使用生成器来实现吗?第一次学习生成器时,我认为生成器可以在某些情况下替换数组,但在尝试构建多维数组时,它们似乎并没有替换数组。
这可能吗?如果是,如何?如果不是,我将如何将它与生成器结合起来?还是只有生成器还是只有数组?
非常感谢
【问题讨论】:
-
您真正希望从食品/非食品示例中看到什么输出?你认为肉、鱼、桌子、凳子是四种不同的反应吗?钥匙应该是什么?食物/非食物?
-
PHP7 之前的生成器不容易实现。然后您可以使用
yield from创建递归样式的行为。因此,在 PHP5 上,通过替换调用堆栈就地仿真的递归仍然是可能的,但我不会那样做。当然,如果只是“使用生成器” - 这是一个坏主意 -
@MarkBaker 老实说,我希望得到与数组相同的输出,但为此使用 yield/generators。因此,与我执行
$return[] = ['Category' => $category, 'Products' => $prodcuts[$category]时的输出相同,并且在 foreach 返回之后。我希望在使用生成器时有相同的输出 -
很清楚,您在这里使用生成器的方式并不比直接遍历数组更好。因为无论如何你在内存中都有数组。像
for ($i = 0; $i < 1000; $i++) yield $i;这样的生成器会比数组[0, 1, 2, ... 999]更好,但是迭代一个本身只是迭代一个数组的生成器是非常荒谬的。 -
像ideone.com/TFUeER 这样的东西(如果为了可读性而正确格式化)在这种情况下比使用生成器更有效,因为对于你的情况,唯一真正的好处是可读性之一
标签: php arrays multidimensional-array generator