実用的なアプローチは、順不同で表示されるものに耐性のある中間データ表現を使用してから、データをもう一度パスしてデータを完成させることです。たとえば、次のようになります。
foreach($elems as $e) {
if($e['type'] == "foo") {
$data[$e["key"]]["foo_data"] = $e["data_foo"];
}
elseif($e['type'] == "bar") {
$data[$e["key"]]["bar"] = new Bar($e);
}
}
foreach ($data as &$d) {
$foo_data = $d["foo_data"];
$d = $d["bar"];
$d->foo_data($foo_data);
}
同様の代替方法は、データを段階的に修正することです。これは、別のループを必要としませんが、修正ロジックを実際のデータ抽出ロジックと結合し、DRYに違反するため、さらに悪化します。
foreach($elems as $e) {
if($e['type'] == "foo") {
if (isset($data[$e["key"]])) {
$data[$e["key"]]->foo_data($e["data_foo"]); // normal operation
}
else {
$data[$e["key"]] = $e["data_foo"]; // temporary result
}
}
elseif($e['type'] == "bar") {
if (isset($data[$e["key"]])) { // incremental fix
$bar = new Bar($e);
$bar->foo_data($data[$e["key"]]);
$data[$e["key"]] = $bar;
else {
$data[$e["key"]]["bar"] = new Bar($e); // normal operation
}
}
}
最後に、もちろん、他の(よく設計された)アプローチを選択して、ループの再実行と「不正なコード」の記述の両方を回避することもできますが、PHPではそれが容易ではなく、疑わしい利益のために大量のコードを記述してしまうことになります。
一般的な推奨事項:一時的なデータ表現を保持し、最後にもう一度ループします。