0

我需要使用yieldyield from相同的功能,但它似乎不能按预期工作,一旦它只产生最后一个yield fromyield(最后一个)。

我的代码是(https://3v4l.org/jFDXh):

function yieldItems() {
    yield 1;
    yield 2;
    yield 3;
    yield from [4, 5, 6];
    yield from [7, 8, 9];
}

var_dump(
    iterator_to_array(
        yieldItems()
    )
);

对于所有 PHP 版本,它只会输出[ 7, 8, 9 ],但对我来说似乎很清楚它应该是[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

但是,如果我通过 a 做同样的foreach事情,一切似乎都很正常。看起来是与 相关的问题iterator_to_array(),但实际上我需要将它转换Generator为数组。

那么,我错过了什么?

4

1 回答 1

0

当我总结时,我意识到问题确实与 . iterator_to_array(),所以我决定在PHP 文档/生成器中进行更深入的搜索,它准确地显示了这种类型的问题。

遵循文档:

yield from不会重置密钥。它保留 Traversable 对象或数组返回的键。因此,某些值可能与另一个yield或 yield from共享一个公共键,在插入数组时,它将用该键覆盖以前的值。

一个重要的常见情况是iterator_to_array()默认返回一个键控数组,这可能导致意外结果。iterator_to_array()有第二个参数use_keys可以设置为FALSE以收集所有值,同时忽略生成器返回的键。

一般来说,这意味着当使用yield / yield from时,它也会输出键(例如,第一个yield将是0),就像它实际存在于纯数组一样。所以下面的代码同样会失败(https://3v4l.org/pWeWT):

function willOutputSingle() {
    yield 'sameKey' => 'originalValue';
    yield 'sameKey' => 'otherValue';
}

var_dump(
    iterator_to_array(
        willOutputSingle()
    )    
); 

// Outputs: [ 'sameKey' => 'otherValue' ]

之所以会发生这种情况,是因为我们产生了[ 'sameKey' => 'originalValue' ]和 then这样的对[ 'sameKey' => 'otherValue' ],所以当我们将其转换为数组时,通过iterator_to_array()结果基本上是:

[ 'sameKey' => 'originalValue',
  'sameKey' => 'otherValue ]

但是 PHP 如何不允许相同的键,只保留最后一个。

解决方案false作为第二个参数传递给iterator_to_array(),因为它不会保留产生的键,因此结果将是一个零索引数组。结果将是:

[ 0 => 'originalValue',
  1 => 'otherValue' ]
于 2020-12-04T18:43:22.080 回答