2013-10-06 4 views
0

Я пытаюсь выяснить, как использовать цикл for для циклического цикла, а также для проверки двух условий. Я сделал это с помощью цикла foreach, но попытался сделать это с помощью цикла for. Ниже приведен блок if и цикл, над которым я работал.Использование цикла for для замены if statement

 if (empty($scores[0]) || 
     empty($scores[1]) || 
     empty($scores[2]) || 
     !is_numeric($scores[0]) || 
     !is_numeric($scores[1]) || 
     !is_numeric($scores[2])) { 
      $scores_string = 'You must enter three valid numbers for scores.'; 
      break; 
    } 

Вот HTML и PHP.

HTML:

<form action="." method="post"> 
    <input type="hidden" name="action" value="process_scores" /> 

    <label>Choose action:</label><br /> 
    <input class="radio" type="radio" name="calculate" value="average" checked="checked">Average<br /> 
    <input class="radio" type="radio" name="calculate" value="total">Total<br /> 
    <input class="radio" type="radio" name="calculate" value="both">Both<br /> 

    <label>Score 1:</label> 
    <input type="text" name="scores[]" 
      value="<?php echo $scores[0]; ?>"/><br /> 

    <label>Score 2:</label> 
    <input type="text" name="scores[]" 
      value="<?php echo $scores[1]; ?>"/><br /> 

    <label>Score 3:</label> 
    <input type="text" name="scores[]" 
      value="<?php echo $scores[2]; ?>"/><br /> 

    <label>&nbsp;</label> 
    <input type="submit" value="Process Scores" /><br /> 

    <label>Scores:</label> 
    <span><?php echo $scores_string; ?></span><br /> 

    <label>Score Total:</label> 
    <span><?php echo $score_total; ?></span><br /> 

    <label>Average Score:</label> 
    <span><?php echo $score_average; ?></span><br /> 
</form> 

PHP:

if (isset($_POST['action'])) { 
$action = $_POST['action']; 
} else { 
$action = 'start_app'; 
} 

switch ($action) { 
case 'start_app': 
    $scores = array(); 
    $scores[0] = 70; 
    $scores[1] = 80; 
    $scores[2] = 90; 
    break; 
case 'process_scores': 
    $scores = $_POST['scores']; 


    // validate the scores 
    for ($i = 0; $i < count($scores); $i++) { 
     if (empty($scores[$i]) || !is_numeric($scores[$i])) { 
     $scores_string = 'You must enter three valid numbers for scores.'; 
     break; 
     } 
    } 


    // process the scores 
    $scores_string = ''; 
    foreach ($scores as $s) { 
     $scores_string .= $s . '|'; 
    } 
    $scores_string = substr($scores_string, 0, strlen($scores_string)-1); 

    // Radio buttons 
    $calculate_type = $_POST['calculate']; 

    switch ($calculate_type) { 
     case 'average': 
      $score_tally = $scores[0] + $scores[1] + $scores[2]; 
      $score_average = $score_tally/count($scores); 
      $score_average = number_format($score_average, 2); 
      break; 
     case 'total': 
      $score_total = $scores[0] + $scores[1] + $scores[2]; 
      $score_total = number_format($score_total, 2);    
      break; 
     case 'both': 
      $score_tally = $scores[0] + $scores[1] + $scores[2]; 
      $score_average = $score_tally/count($scores); 
      $score_total = $scores[0] + $scores[1] + $scores[2]; 
      $score_total = number_format($score_total, 2); 
      $score_average = number_format($score_average, 2); 
      break; 
    } 

    break; 
case 'process_rolls': 
    $number_to_roll = $_POST['number_to_roll']; 

    $total = 0; 
    // $count = 0; 
    $max_rolls = -INF; 

    for ($count = 0; $count < 1000; $count++) { 
     $rolls = 1; 
     while (mt_rand(1, 6) != 6) { 
      $rolls++; 
     } 
     $total += $rolls; 
     $max_rolls = max($rolls, $max_rolls); 
    } 
    $average_rolls = $total/$count; 

    break; 


} 

При этом цикл под Сверяет оценки на месте, я не дала никаких результатов, когда есть недостоверные данные.

ответ

2

Я бы посмотрел на array_reduce, так как это в основном то, что вы делаете: сокращение массива до булева.

if(array_reduce(
    $scores, 
    function($a,$b) {return $a || empty($b) || !is_numeric($b);}, 
    false)) { 
     $scores_string = "You must enter three valid numbers for scores."; 
} 
+0

"{return $ a || empty ($ b) ||! Is_numeric ($ b);}" Как это работает? –

+0

'array_reduce()' будет перебирать все элементы. '$ a' является копией кумулятивного результата из предыдущих итераций (внутренняя переменная в' array_reduce() '). Параметр функции должен обновить его для текущей итерации ('$ b' - текущий элемент) и вернуть новое обновленное значение. – geomagas

2

Так как вы просили for цикла:

for ($i = 0; $i < count($scores); $i++) 
    if (empty($scores[$i]) || !is_numeric($scores[$i])) { 
     $scores_string = 'You must enter three valid numbers for scores.'; 
     break; 
    } 
+0

Я пробовал ваш пример, и ничего не получаю. Оценки заполняются пользовательским вводом. Все текстовые поля имеют одинаковый атрибут «score []». Я использовал $ scores = $ _POST ['score'] для получения пользовательских записей. На данный момент с вашим примером на месте, я не получаю сообщение об ошибке с указанием пустого или недопустимого числа. – user1890525

+0

Я немного смущен. Вы имеете в виду, что не получаете сообщения об ошибке, где вы должны? Или что вы получаете _no вывод с использованием правильных данных? Если это первый, проверьте состояние внутри 'if'. Если это последний, то да, это должно работать. – geomagas

+0

Правильно! Я должен получить $ scores_string, когда поле ввода пустое или isNAN. Использование блока if, опубликованного выше, отлично работает, поэтому я знаю, что нет проблемы с $ scores_string. – user1890525

1

Я не понимаю, почему вы тестирование, если оценка пуста. Если оценка пуста, то is_numeric возвращает false.

Моя версия for цикла:

for ($i = 0, $len = count($scores); $i < $len and is_numeric($scores[$i]); $i++) {} 
if ($i !== $len) echo 'You must enter three valid numbers for scores.'; 

редактировать: Если вам нужно проверить, если есть ровно 3 числовые элементы в массиве (как @geomagas предполагают), то:

for ($i = 0; $i < 3 and is_numeric($scores[$i]); $i++) {} 

// If $i is less then 3 it's mean that one of items are not set or it's not numeric 
if ($i < 3) echo 'You must enter three valid numbers for scores.'; 

редактировать : Третье решение, которое обрабатывает ситуацию, когда массив неправильно проиндексирован. Я отправляю это просто для удовольствия, отказываясь использовать empty функцию, которая @geomagas принуждая меня;)

$scores = array('234', '52', '245'); 

for (reset($scores); $valid = is_numeric(current($scores)) and next($scores);) {} 

if (! $valid) echo 'You must enter three valid number for scores.'; 
+0

Пожалуйста, см. Мой комментарий к ответу abstr, я думаю, это относится и к вашему. – geomagas

+0

Я добавил второй пример, который решает эту проблему. – ofca

+0

Нет, нет, я не это имел в виду. Я думал о возможности _replacing_ 'empty()' с 'isset()' вместо того, чтобы исключать его. Что, если '$ score' выглядит так:' Array ([0] => 4, [2] => 9) '? _NOTE: Я все еще думаю, что это не относится к вопросу. – geomagas

0

empty() не следует использовать, так 0 считается пустым, а также является числовым.

+0

Почти хороший момент, хотя это не было частью вопроса. Но выполняет ли 'is_numeric' тест, если установлена ​​переменная? – geomagas

+0

'$ score [$ i]' всегда задано, поскольку цикл for подсчитывал размер массива до использования. – abstr

+0

Играя в защитника _devil_, предположим, что '$ score' является' Array ([0] => 4, [2] => 9, [5] => 12) '. _Посмотреть также: Комментарии к запросу ofca_ – geomagas

Смежные вопросы