2017-06-16 89 views
4

我很高兴PHP 7.1引入了the iterable pseudo-typePHP可迭代到数组或遍历

现在虽然这只是循环遍历这种类型的参数,但我不清楚当你需要将它传递给只接受array或仅仅接受Traversable的PHP函数时该怎么做。例如,如果你想要做一个array_diff,并且你的iterableTraversable,你会得到一个array。相反,如果您调用带有迭代器的函数,则如果iterablearray,则会发生错误。 (不是:iterator_to_array)和iterable_to_traversable

我正在寻找一种解决方案,以避免我的函数中的条件只是为了照顾这种差异,并且不依赖于我定义自己的全局函数。

使用PHP 7.1

回答

4

不知道这是你在寻找,但这是做它的最短途径。

$array = []; 
array_push ($array, ...$iterable); 

我不是很确定它为什么有效。只是,我发现你的问题有趣,我开始用PHP摆弄

完整的示例:

<?php 

function some_array(): iterable { 
    return [1, 2, 3]; 
} 

function some_generator(): iterable { 
    yield 1; 
    yield 2; 
    yield 3; 
} 

function foo(iterable $iterable) { 
    $array = []; 
    array_push ($array, ...$iterable); 
    var_dump($array); 

} 

foo(some_array()); 
foo(some_generator()); 

这将是很好,如果与功能array()作品,但因为它是一个语言结构有点特殊。它也不保留关联数组中的键。

+1

这是可行的,因为array_push需要一个可变数量的参数,并且你用...将这个iterable解包到一个参数列表中。由于需要在范围中引入额外的变量,然后对其进行变更,因此对我来说这不是一个可接受的解决方案。 –

+0

@JeroenDeDauw我知道...展开它,但在数组()不以相同的方式工作,所以有一些奇怪的事情。我同意这不是一个可以接受的解决方案,事实上,我认为这在7.1中是不可能的,但是我发现考虑到限制(不定义函数和使用条件)是最接近的, –

1

有什么样iterable_to_array和iterable_to_traversable

只是这些地方添加到您的项目,他们不占用大量的空间,给你你要的确切的API。

function iterable_to_array(iterable $it): array { 
    if (is_array($it)) return $it; 
    $ret = []; 
    array_push($ret, ...$it); 
    return $ret; 
} 

function iterable_to_traversable(iterable $it): Traversable { 
    yield from $it; 
}