一种实用的方法是使用中间数据表示,该表示可以容忍出现乱序的东西,然后再次传递数据以完成它,例如:
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 并没有让这变得容易,您最终会编写大量代码以获得可疑的好处。
一般建议:保留一个临时数据表示,最后再循环一次。