Я только что написал часть генератора и достиг точки, в которой он функционирует правильно, но нуждается в некотором рефакторинге. Структура метода заключается в следующем:Разделение генераторов PHP
public function getFlattenedList(array $elements) {
foreach ($elements as $element) {
if ($this->someCondition($element)) {
// A pile of stuff here
if ($anotherCondition) {
for ($i = 0; $i < $this->someValue(); $i++) {
yield $this->anotherOperation($element);
}
}
}
else {
yield $this->someOperation($element);
}
}
}
Этот метод является крупным/сложным. Самое очевидное, что нужно сделать, - это переместить тело ветви if в свой собственный метод. Что-то вроде этого
public function getFlattenedList(array $elements) {
foreach ($elements as $element) {
if ($this->someCondition($element)) {
// ???
$this->getFlattenedElement($element);
}
else {
yield $this->someOperation($element);
}
}
}
private function getFlattenedElement() {
// A pile of stuff here
if ($anotherCondition) {
for ($i = 0; $i < $this->someValue(); $i++) {
yield $this->anotherOperation($element);
}
}
}
Но, конечно, я не могу просто вернуть результат этой новой функции, поскольку она также является генератором. (И я хочу, чтобы генератор, поэтому работа выполняется только тогда, когда запрашивается значение.) То, что я сделал, чтобы сделать эту работу, добавив еще одну петлю, внутри тела, если условие:
public function getFlattenedList(array $elements) {
foreach ($elements as $element) {
if ($this->someCondition($element)) {
foreach ($this->getFlattenedElement($element) as $flattened) {
yield $flattened;
}
}
else {
yield $this->someOperation($element);
}
}
}
Можно ли как-то избежать необходимости добавлять этот цикл, сохраняя поведение генератора и хорошо разбираясь в методе? Раньше я не использовал генераторы, так что, возможно, не было ничего очевидного.
Почему бы не устранить 'foreach ($ this-> getFlattenedElement ($ element) as $ flattened) { yield $ flattened; } 'loop с простым' yield $ this-> getFlattenedElement ($ element); 'Попробуйте! Ваш цикл обрабатывается генератором 'getFlattenedElement()' –
Я пробовал это, но тогда мой тест не прошел, поэтому он определенно не эквивалентен. Если я это сделаю, он даст генератор и, следовательно, будет иметь результат типа «Генератор» нет? –
Ну нет причин, почему это не должно работать: он не должен давать генератор, но должен давать результат от генератора .... рекурсивные генераторы работают –