2017-06-16 93 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; 
}