Постигая азы, решил попрактиковаться стая себе свои задачи исходя из своего уровня. Задачу поставил следующую: Турнирная таблица футбольных команд. Для начал хотелось бы посчитать очки исходя из результата игры. За результат игры отвечают два массива. Точнее их значения. Ключ - это один матч. 5 ключей = 5 игр. В примере указаны следующие результаты (1:0, 0:0, 3:0, 1:3, 0:4) $clubZabGoly = array (1=>1, 2=>0, 3=>3, 4=>1, 5=>0); $clubPropGoly = array (1=>0, 2=>0, 3=>0, 4=>3, 5=>4); У команды сейчас - 7 очков (за победу 3 очка, за ничью 1 очко, за поражение 0 очков). Логика такая, если "забитыеГолыКлуба" больше "пропущенныхГоловКлуба", к переменной "очки" добавляем 3, в противном случае если голы равны, прибавляем 1, в противном случае 0. Примерно вижу вот такой код, но заведомо знаю, что это не верно. подскажите куда копать. Код (Text): function ochki ($array) { $ochki = 0; $clubZabGoly = 0; $clubPropGoly = 0; foreach ($array as $k => $v) { if (clubZabGoly > $clubPropGoly) { $ochki += 3; } else if ($clubZabGoly == $clubPropGoly) { $ochki += 1; } else {$ochki = 0;} } return $ochki; }
Тут больше цикл FOR подходит, а не FOREACH. А вообще, я бы всё в одном массиве сделал. Зачем вам два?
я делал так. ставишь палец на каждую строчку и пишешь, что она делает и зачем. вот когда это проделано, можно говорить, куда копать. пока из кода видно, что clubZabGoly и clubPropGoly не меняются.
Дело в том, что команд будет много (15 например). И нужен какой-либо порядок. Например, что-бы каждый ключ отвечал за отдельный тур (0[1 тур], 1[2 тур], 2[3 тур]). Тогда можно будет связывать массивы (забитых и пропущенных голов) логически. Была мысль создавать отдельно взятый массив для каждой отдельной игры, но тоже ни чего не вышло. Еще раз повторюсь, эти задания для освоения ПХП и его возможностей. В процессе столкнулся с данной задачей и понял, что foreach, работает только с одним массивом, а перебирать с помощью него два разных массива и еще и сравнивать их значения не получится. Во всяком случае сейчас. Вот и спрашиваю... возможно действительно это тупик. А так, я рассмотрю любые варианты, мне это все сейчас полезно. Но мне кажется, что это правильный сбор данных. Я имею ввиду массив забитых и пропущенных голов. Ведь каждый ключ это поле, от куда должно выбираться значение и сравниваться с со значениями аналогичного массива. Про вариант FOR, не понял. Так как он не разделяет на ключ и значение. Просветите, буду рад.
в исходных начальных данных и с for можно попробовать так PHP: function ochki ($clubZabGoly, $clubPropGoly) { $ochki = 0; for ($index = 0; $index < count($clubPropGoly); $index++) { if ($clubZabGoly[$index] > $clubPropGoly[$index]) { $ochki += 3; } else if ($clubZabGoly[$index] == $clubPropGoly[$index]) { $ochki += 1; } else { $ochki = 0; } } return $ochki; } $clubZabGoly = array (1=>1, 2=>0, 3=>3, 4=>1, 5=>0); $clubPropGoly = array (1=>0, 2=>0, 3=>0, 4=>3, 5=>4); $ochki = ochki ($clubZabGoly, $clubPropGoly); var_dump($ochki);
Спасибо. Код работает, но считает не верно. Хотя в вышеуказанном массиве все сработало = 5 очков, как и должно быть. Но стоит изменить значение, например Код (Text): $clubZabGoly = array (1 => 2, 2 => 1, 3 => 3, 4 => 4, 5 => 1); $clubPropGoly = array (1 => 0, 2 => 0, 3 => 1, 4 => 2, 5 => 0); и результат уже не правильный, вместо 15 - 13 очков.
PHP: function ochki($zab, $prop) { $score=0; foreach($zab as $i=>$v) { $score += ( $zab[$i]>$prop[$i] ? 3 : ($zab[$i]==$prop[$i] ? 1 : 0 ) ); }//for return $score; } $clubZabGoly = array(1=>2,2=>1,3=>3,4=>4,5=>1); $clubPropGoly= array(1=>0,2=>0,3=>1,4=>2,5=>0); echo ochki($clubZabGoly,$clubPropGoly); // 15
Отлично. Все работает верно. Еще хотелось бы понять логику: - Например почему в foreach, вместо $k идет $i? - Почему в foreach, перебирается лишь первый массив $zab as $i=>$v? - Почему в условии у массивов берется [$i], ведь по логике вещей - это ключи, а не значения. А очки рассчитываются исходя из сравнения значений. А так все понятно. Спасибо.
Ответы на все твои вопросы всего в одном разделе документации. https://php.ru/manual/control-structures.foreach.html
Понятно стало то что вместо $k или $v можно поставлять любые произвольные переменные. Но что касается третьего моего замечания, то вопрос остается открытым и в мануале не разбирается. [$i] в примере - @runcore, является ключом. Или все же значением?
да, неправильно написал. для начала надо было вот так: принимаем за данность, что оба массива считаются от 1 до 5.
Понял. Это просто определение элемента массива. А то, что сравнивать будут значение - это по умолчанию. Нет. Данностью статическое значение быть не может. Потому как игр будет, не 5 и не 25. А к примеру 34.
это уже следующий этап изучения циклов и массивов индекс последнего элемента можно вычислить через count($array), но тогда в массиве не должно быть "пропусков"
Некоторые команды сыграли на одну игру меньше, то есть у них не может быть 5 матчей. Проблема была в том, что в последнем шаге условия, вместо: Код (Text): $ochki += 0; стоит Код (Text): $ochki = 0; --- Добавлено --- Загвоздка была в том, что во время условия, сравнивались не элементы массива, а сами массивы. runcore - первым кто обратил на это внимания. После этого стало понятно, что в принципе даже fjreach не обязательно было подключать, а можно обойтись стандартным for. --- Добавлено --- Вот как раз по поводу следующего этапа. На данный момент имеется турнирная таблица, содержание которой высчитывается с помощью 6 функций. Которые в свою очередь используют данные двух массивов (для каждой команды) - забитых и пропущенных голов. Функции считают, количество побед, ничей и поражений, забитых, пропущенных и разницы голов, а также очки. За пример взяты первые три клуба российской премьер лиги (Ростов, ЦСКА, Зенит). Вот общий, готовый код: Код (Text): <?php $RostovZ = array (1, 2, 0, 3, 1, 1, 1, 0, 1, 2, 0, 3, 2, 1, 2, 1, 1, 1, 1, 2, 0, 2, 0, 1); $RostovP = array (1, 1, 0, 0, 1, 2, 0, 1, 0, 1, 3, 2, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0); $CSKAZ = array (1, 2, 1, 2, 2, 2, 1, 2, 6, 1, 2, 3, 0, 2, 1, 0, 1, 0, 1, 0, 2, 0, 7, 1); $CSKAP = array (0, 0, 0, 0, 1, 1, 0, 2, 4, 1, 0, 2, 0, 0, 2, 2, 1, 2, 0, 2, 0, 2, 1, 1); $ZenitZ = array (2, 4, 3, 1, 0, 3, 1, 2, 1, 2, 3, 2, 5, 0, 0, 3, 1, 1, 0, 4, 2, 2, 2, 5); $ZenitP = array (1, 1, 0, 0, 2, 1, 3, 2, 1, 2, 0, 2, 1, 0, 2, 0, 4, 1, 0, 2, 0, 0, 0, 2); function ochki ($zab, $prop) { $ochki = 0; foreach ($zab as $i => $v) { $ochki += ($zab[$i] > $prop[$i] ? 3 : ($zab[$i] == $prop[$i] ? 1 : 0)); } return $ochki; } function vin ($zab, $prop) { $vin = 0; for ($i = 0; $i < count($zab); $i++) { if ($zab[$i] > $prop[$i]) { $vin += 1; } } return $vin; } function nich ($zab, $prop) { $nich = 0; for ($i = 0; $i < count($zab); $i++) { if ($zab[$i] == $prop[$i]) { $nich += 1; } } return $nich; } function por ($zab, $prop) { $por = 0; for ($i = 0; $i < count($prop); $i++) { if ($zab[$i] < $prop[$i]) { $por += 1; } } return $por; } function zpg ($a) { $zpg = 0; foreach ($a as $v) { $zpg += $v; } return $zpg; } function raznicaGolov ($a, $b) { $raznicaGolov = $a - $b; return $raznicaGolov; } $ochkiRostov = ochki ($RostovZ, $RostovP); $ochkiCSKA = ochki ($CSKAZ, $CSKAP); $ochkiZenit = ochki ($ZenitZ, $ZenitP); $vinRostov = vin ($RostovZ, $RostovP); $nichRostov = nich ($RostovZ, $RostovP); $porRostov = por ($RostovZ, $RostovP); $vinCSKA = vin ($CSKAZ, $CSKAP); $nichCSKA = nich ($CSKAZ, $CSKAP); $porCSKA = por ($CSKAZ, $CSKAP); $vinZenit = vin ($ZenitZ, $ZenitP); $nichZenit = nich ($ZenitZ, $ZenitP); $porZenit = por ($ZenitZ, $ZenitP); $zgRostov = zpg ($RostovZ); $zgCSKA = zpg ($CSKAZ); $zgZenit = zpg ($ZenitZ); $pgRostov = zpg ($RostovP); $pgCSKA = zpg ($CSKAP); $pgZenit = zpg ($ZenitP); $raznicaGolovRostov = raznicaGolov ($zgRostov, $pgRostov); $raznicaGolovCSKA = raznicaGolov ($zgCSKA, $pgCSKA); $raznicaGolovZenit = raznicaGolov ($zgZenit, $pgZenit); ?> <table border="1" cellpadding="3" cellspacing="0" style="text-align:center;"> <tr> <td>Команда</td> <td>Победы</td> <td>Ничьи</td> <td>Поражения</td> <td>Забитые голы</td> <td>Пропущенные голы</td> <td>Разница голов</td> <td>Очки</td> </tr> <tr> <td>Ростов</td> <td><?php echo $vinRostov; ?></td> <td><?php echo $nichRostov; ?></td> <td><?php echo $porRostov; ?></td> <td><?php echo $zgRostov; ?></td> <td><?php echo $pgRostov; ?></td> <td><?php echo $raznicaGolovRostov; ?></td> <td><?php echo $ochkiRostov; ?></td> </tr> <tr> <td>ЦСКА</td> <td><?php echo $vinCSKA; ?></td> <td><?php echo $nichCSKA; ?></td> <td><?php echo $porCSKA; ?></td> <td><?php echo $zgCSKA; ?></td> <td><?php echo $pgCSKA; ?></td> <td><?php echo $raznicaGolovCSKA; ?></td> <td><?php echo $ochkiCSKA; ?></td> </tr> <tr> <td>Зенит</td> <td><?php echo $vinZenit; ?></td> <td><?php echo $nichZenit; ?></td> <td><?php echo $porZenit; ?></td> <td><?php echo $zgZenit; ?></td> <td><?php echo $pgZenit; ?></td> <td><?php echo $raznicaGolovZenit; ?></td> <td><?php echo $ochkiZenit; ?></td> </tr> </table> И вот пришел момент следующего этапа. Как бы этот весь огромнейший код теперь уменьшить.Например использовать не все три строки (а в конечном итоге 15) таблицы (tr), а одну. Ведь значения должны подставляться через переменную. И как это реализовать еще не прозрел. Возможно путь в этом случае совсем иной. P.S. Возможно стоит создать новую тему?
функцию zpg () можно смело заменить на нативную array_sum() --- Добавлено --- для начала можно простить код PHP: function analiz($zab, $prop) { $ochki = $vin = $nich=$por=0; foreach ($zab as $i => $v) { $ochki += ($zab[$i] > $prop[$i] ? 3 : ($zab[$i] == $prop[$i] ? 1 : 0)); if ($zab[$i] > $prop[$i]) { $vin += 1; } else if ($zab[$i] == $prop[$i]) { $nich += 1; } else if ($zab[$i] < $prop[$i]) { $por += 1; } } return array('ochki'=>$ochki,'vin'=>$vin,'nich'=>$nich,'por'=>$por); } $analizRostov = analiz($RostovZ, $RostovP); $analizCSKA = analiz($CSKAZ, $CSKAP); $analizZenit = analiz($ZenitZ, $ZenitP); $zgRostov = array_sum($RostovZ); $zgCSKA = array_sum($CSKAZ); $zgZenit = array_sum($ZenitZ); $pgRostov = array_sum($RostovP); $pgCSKA = array_sum($CSKAP); $pgZenit = array_sum($ZenitP); $raznicaGolovRostov= $zgRostov- $pgRostov; $raznicaGolovCSKA = $zgCSKA - $pgCSKA; $raznicaGolovZenit = $zgZenit - $pgZenit; а вообще нужно прийти к единому большому массиву, чтобы тупо в цикле перебирать результаты и строить любые таблицы автоматически
Спасибо runcore. Сколько полезной инфы, которой не знал. Про то что в одной функции можно вычислить сразу несколько операций не знал, хотя мысля посещала. Вот это наверное то, что нужно. Все в одной функции реализовать. Про array_sum, тоже теперь буду знать. Очень удобно. Но почему-то функция analiz - выводит лишь Array. То есть к ассоциативному? или имеется ввиду многомерность? И как подобное реализуется на практике, у профи? Получается создается один массив?
пример: PHP: <?php $input = array( 'Ростов' => array( 'Z'=>array(1, 2, 0, 3, 1, 1, 1, 0, 1, 2, 0, 3, 2, 1, 2, 1, 1, 1, 1, 2, 0, 2, 0, 1) ,'P'=>array(1, 1, 0, 0, 1, 2, 0, 1, 0, 1, 3, 2, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0) ), 'ЦСКА'=>array( 'Z'=> array(1, 2, 1, 2, 2, 2, 1, 2, 6, 1, 2, 3, 0, 2, 1, 0, 1, 0, 1, 0, 2, 0, 7, 1) ,'P'=> array(0, 0, 0, 0, 1, 1, 0, 2, 4, 1, 0, 2, 0, 0, 2, 2, 1, 2, 0, 2, 0, 2, 1, 1) ), 'Зенит'=>array( 'Z'=> array(2, 4, 3, 1, 0, 3, 1, 2, 1, 2, 3, 2, 5, 0, 0, 3, 1, 1, 0, 4, 2, 2, 2, 5) ,'P'=> array(1, 1, 0, 0, 2, 1, 3, 2, 1, 2, 0, 2, 1, 0, 2, 0, 4, 1, 0, 2, 0, 0, 0, 2) ) ); function analiz($zab, $prop) { $ochki=$vin=$nich=$por=0; foreach ($zab as $i => $v) { $ochki+= ($zab[$i]>$prop[$i] ? 3 : ($zab[$i]==$prop[$i] ? 1 : 0)); $vin += $zab[$i]> $prop[$i] ? 1:0; $nich += $zab[$i]==$prop[$i] ? 1:0; $por += $zab[$i]< $prop[$i] ? 1:0; }//foreach return array('ochki'=>$ochki,'vin'=>$vin,'nich'=>$nich,'por'=>$por); } ?> <table border="1" cellpadding="3" cellspacing="0" style="text-align:center;"> <tr> <td>Команда</td> <td>Победы</td> <td>Ничьи</td> <td>Поражения</td> <td>Забитые голы</td> <td>Пропущенные голы</td> <td>Разница голов</td> <td>Очки</td> </tr> <?php foreach($input as $k=>$v) { $analiz = analiz( $v['Z'], $v['P'] ); $zg= array_sum($v['Z']); $pg= array_sum($v['P']); echo '<tr> <td>'.$v['name'].'</td> <td>'.$analiz['vin'].'</td> <td>'.$analiz['nich'].'</td> <td>'.$analiz['por'].'</td> <td>'.$zg.'</td> <td>'.$pg.'</td> <td>'.($zg-$pg).'</td> <td>'.$analiz['ochki'].'</td> </tr>'; }//foreach ?> </table>
Спасибо большое. Все понятно и доступно. Теперь буду ставить себе новые задачи. В которых значения буду браться из базы данных. Спасибо тезка. Про ассоциативный массив я знаю. Но целью было освоение числового массива, познание его возможностей А что используют в данном случае профи? Популярные, спортивные сайты например Ассоциативный массив?
Они используют базу данных и SQL. При обработке результатов запроса, скорее всего, ассоциативные массивы. Они гораздо удобнее. Если использовать числовые, то при вставке нового столбца в таблицу где-нибудь в середину, придётся править и пхп-код.
То, что все идет из базы это понятно. Важно как они генеряться в коде? Через массив? Через ассоциативный или числовой? По вашему посту понял, что через ассоциативный. Спасибо.
Там может быть и объект. Одну и ту же задачу можно решить кучей разных способов. Правильных нет. Есть не правильные Стремиться нужно к тому, чтобы полученные из базы данные не требовали никакой обработки. Вы сделали SQL-запрос, получили результат и сразу отправили на вывод. Ничего больше не высчитывая. Ну, можно немного причесать для эстетики.