【问题标题】:"yield" and "yield from" at same function同一功能的“产量”和“产量”
【发布时间】:2021-03-16 19:53:45
【问题描述】:

我需要在同一个函数中使用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 ]

但是,如果我通过foreach 做同样的事情,一切似乎都很正常。貌似是iterator_to_array()相关的问题,其实我需要把这个Generator转成数组。

那么,我错过了什么?

【问题讨论】:

    标签: php yield yield-from


    【解决方案1】:

    当我总结的时候,我意识到这个问题确实与iterator_to_array()有关,所以我决定在PHP Documentation / Generators中更深入地搜索,它恰好显示了这种类型的问题。

    按照文档:

    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' ][ 'sameKey' => 'otherValue' ] 这样的对,所以当我们通过 iterator_to_array() 将其转换为数组时,结果基本上是:

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

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

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

    [ 0 => 'originalValue',
      1 => 'otherValue' ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-14
      • 2016-08-25
      • 1970-01-01
      • 2018-07-30
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      • 2021-02-23
      相关资源
      最近更新 更多