家庭控制器:
//my query in repository
public function Available (){
$Sql= ' SELECT DISTINCT
a.property_id, a.date, a.minimum_stay,
a.maximum_stay,a.quantity,
p.duration, p.persons, p.amount,
p.extra_person_price, p.minimum_stay AS price_minimum_stay,
p.maximum_stay AS price_maximum_stay, p.weekdays
FROM availabilities AS a
JOIN prices AS p
ON a.property_id=p.property_id
WHERE a.minimum_stay >0
AND a.maximum_stay < 22
AND a.date >= p.period_from
AND a.date <= p.period_till
';
class HomeController extends Controller
{
/**
* @Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
$hotel_information = $this->retrieveInformationFromDB();
return $this->render('Home/index.html.twig', array(
'hotel_information'=>$hotel_information
)
);
}
private function retrieveInformationFromDB(){
$em= $this->getDoctrine()->getEntityManager();
$availables = $em->getRepository('AppBundle:Availabilities')->Available();
$hotel_information=array();
for($i = 0; $i< count($availables) ; $i++) {
$date = $availables[$i]['date'];
$duration = $availables[$i]['duration'];
$amount = $availables[$i]['amount'];
$extra_person_price = $availables[$i]['extra_person_price'];
$persons = explode('|',$availables[$i]['persons']);
$hotel_information_placeholder = $this->calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration);
$hotel_information = array_merge($hotel_information, $hotel_information_placeholder);
}
return $hotel_information;
}
private function calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration){
foreach ($persons as $person) {
if ($person > 1) {
$price_per_person[] = array(
"date" => $date,
"person" => $person,
"price_person" => number_format((($person * $extra_person_price) + $amount) / 100, 2, '.', ','),
"day2"=>number_format(((($person * $extra_person_price) + $amount)*2) / 100, 2, '.', ','),
"day3"=>number_format(((($person * $extra_person_price) + $amount)*3) / 100, 2, '.', ','),
"day4"=>number_format(((($person * $extra_person_price) + $amount)*4) / 100, 2, '.', ','),
"day5"=>number_format(((($person * $extra_person_price) + $amount)*5) / 100, 2, '.', ','),
"day6"=>number_format(((($person * $extra_person_price) + $amount)*6) / 100, 2, '.', ','),
"day7"=>number_format(((($person * $extra_person_price) + $amount)*7) / 100, 2, '.', ','),
);
} else {
$price_per_person[] = array(
"date" => $date,
"person" => $person,
"price_person" => number_format($amount / 100, 2, '.', ','),
"day2"=>number_format(($amount * 2)/ 100, 2, '.', ','),
"day3"=>number_format(($amount * 3)/ 100, 2, '.', ','),
"day4"=>number_format(($amount * 4)/ 100, 2, '.', ','),
"day5"=>number_format(($amount * 5)/ 100, 2, '.', ','),
"day6"=>number_format(($amount * 6)/ 100, 2, '.', ','),
"day7"=>number_format(($amount * 7)/ 100, 2, '.', ',')
);
}
}
return $price_per_person;
}
在功能私人功能calculatePricePerPerson 我正在计算一个人的价格和基于日期的天数。目前我的计算方式是这样的。问题是计算的数字是从1到21,因此我的foreach循环变得非常长而且非常难看。所以我的问题是如何以更好,更有效的方式做到这一点。
答案 0 :(得分:1)
此代码有几个可以优化的冗余点。 原始代码:
private function calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration){
foreach ($persons as $person) {
if ($person > 1) {
$price_per_person[] = array(
"date" => $date,
"person" => $person,
"price_person" => number_format((($person * $extra_person_price) + $amount) / 100, 2, '.', ','),
"day2"=>number_format(((($person * $extra_person_price) + $amount)*2) / 100, 2, '.', ','),
"day3"=>number_format(((($person * $extra_person_price) + $amount)*3) / 100, 2, '.', ','),
"day4"=>number_format(((($person * $extra_person_price) + $amount)*4) / 100, 2, '.', ','),
"day5"=>number_format(((($person * $extra_person_price) + $amount)*5) / 100, 2, '.', ','),
"day6"=>number_format(((($person * $extra_person_price) + $amount)*6) / 100, 2, '.', ','),
"day7"=>number_format(((($person * $extra_person_price) + $amount)*7) / 100, 2, '.', ','),
);
} else {
$price_per_person[] = array(
"date" => $date,
"person" => $person,
"price_person" => number_format($amount / 100, 2, '.', ','),
"day2"=>number_format(($amount * 2)/ 100, 2, '.', ','),
"day3"=>number_format(($amount * 3)/ 100, 2, '.', ','),
"day4"=>number_format(($amount * 4)/ 100, 2, '.', ','),
"day5"=>number_format(($amount * 5)/ 100, 2, '.', ','),
"day6"=>number_format(($amount * 6)/ 100, 2, '.', ','),
"day7"=>number_format(($amount * 7)/ 100, 2, '.', ',')
);
}
}
return $price_per_person;
}
乍一看,似乎if
和else
块中的代码非常相似,唯一的区别是额外的人物。通过关注该元素,您可以避免使用两次几乎相同的代码:
private function calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration){
foreach ($persons as $person) {
if ($person > 1) {
$amount += $person * $extra_person_price;
}
$price_per_person[] = array(
"date" => $date,
"person" => $person,
"price_person" => number_format($amount / 100, 2, '.', ','),
"day2"=>number_format(($amount * 2)/ 100, 2, '.', ','),
"day3"=>number_format(($amount * 3)/ 100, 2, '.', ','),
"day4"=>number_format(($amount * 4)/ 100, 2, '.', ','),
"day5"=>number_format(($amount * 5)/ 100, 2, '.', ','),
"day6"=>number_format(($amount * 6)/ 100, 2, '.', ','),
"day7"=>number_format(($amount * 7)/ 100, 2, '.', ',')
);
}
return $price_per_person;
}
不是在if
的每个分支中填充数组,而是将人员价格添加到$amount
。由于$amount
根据具体情况具有不同的值,因此else变得无用且数组被一次性填充。
短得多,但还没结束。条目day2
到day7
几乎完全相同,唯一的区别是密钥末尾的数字和$amount
乘以的因子。偶然的,它们在每一行中总是相同的,所以让我们把它缩小到一个循环:
private function calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration){
foreach ($persons as $person) {
if ($person > 1) {
$amount += $person * $extra_person_price;
}
$tmp = array(
"date" => $date,
"person" => $person,
"price_person" => number_format($amount / 100, 2, '.', ',')
);
for ($x = 2; $x <= 7; ++$x) {
$tmp["day$x"] = number_format(($amount * $x)/ 100, 2, '.', ',');
}
$price_per_person[] = $tmp;
}
return $price_per_person;
}
在此步骤中,我创建了一个临时数组,其中填充了静态数据,然后是for
循环,该循环将$tmp
的条目添加到每个天数必须处理。然后将临时数组分配给$price_per_person[]
,以便一切都像在第一个版本中那样工作。而且由于现在处理了一个循环,你可以通过修改for的限制来增加或减少必须计算和显示的天数 - 目前为7。
这就是你可以得到的最短而不失清晰度。此外,通过删除冗余,您可以立即更新代码,而不是 - 尝试 - 更新 - 大致相同的代码的每次出现。