Use if inside foreach

5

I am trying to change the order in which the results appear within a loop using foreach. What I need is for numbers greater than five to appear first, followed by the rest of the numbers. So I tried something like this:

$numeros = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
echo '<ul>';
foreach($numeros as $numero){
    if($numero > 5){
        echo '<li>'.$numero.'</li>';
    }else{
        echo '<li>'.$numero.'</li>';
    }
}
echo '</ul>';

But it is not working.

    
asked by anonymous 09.05.2014 / 19:47

5 answers

15

I just responded to illustrate what's going on. What happens in your code is that you have created a condition that can be read like this:

  • Iterate all elements
  • If it is larger than five, print.
  • otherwise, print.
  • There they all appear. Try this code with the same problem but with a "hint" inside if to understand what happened:

    $numeros = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
    echo '<ul>';
    foreach($numeros as $numero){
        if($numero > 5){
            echo '<li>MAIOR QUE CINCO - '.$numero.'</li>';
        }else{
            echo '<li>MENOR OU IGUAL - '.$numero.'</li>';
        }
    }
    echo '</ul>';
    

    A simplistic solution would be to separate the loops (even though in a practical case we would probably have much better solutions):

    $numeros = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
    echo '<ul>';
    foreach($numeros as $numero){
        if($numero > 5){
            echo '<li>'.$numero.'</li>';
        }
    }
    foreach($numeros as $numero){
        if($numero <= 5) {
            echo '<li>'.$numero.'</li>';
        }
    }
    echo '</ul>';
    

    We look like this:

  • Iterate all elements
  • If it is larger than five, print.
  • Iterate all elements AGAIN
  • Only if it is less than or equal to five, print.
  •   

    This is a didactic response. In the practical case, several optimizations could be made depending on the use of the data.

        
    09.05.2014 / 19:52
    3

    You can also treat arrays before printing, as follows:

    $numeros = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
    asort($numeros); // necessário se o array estiver desordenado
    $num = 5; // valor limite
    $pos = array_search($num,$numeros); // pega a posição do array conforme valor determinado
    $numerosMenores = array_slice($numeros,0,$pos); // pega parte do array com os numeros menores
    $numerosMaiores = array_slice($numeros,$pos); // pega parte do array com os numeros maiores
    $numeros = array_merge($numerosMaiores, $numerosMenores); //funde os arrays
    
    foreach($numeros as $numero){
        echo '<li>'.$numero.'</li>';
    }
    echo '</ul>';
    

    OBS: If your array is out of order you will first need to sort it, asort($numero) , or this will not work.

        
    09.05.2014 / 20:12
    2

    Although with PHP you can do many things in many different ways this does not mean that you will hammer a screw just because you did not find the right one.

    With this in mind, consider what you want to do: "A condition within an iteration". What will this condition do? "It will filter a certain result before running the routine on it."

    So, use the right or most appropriate tool for the task in question: array_filter ()

    This function will receive a given input array and filter it according to the function passed as the second argument. This function can be a string for some function known to the program (such as a native function, for example), an anonymous function, or even an object method.

    $data = array( 1,2,3,4,5,6,7,8,9,10 );
    
    $data = array_filter(
    
        $data,
    
        function( $current ) {
    
            return ( $current <= 5 );
        }
    );
    

    $ data , now has only five elements, one to five.

    "But I have to print everything"

    Here is where the various possibilities come in. One cool thing would be to compute the difference of the input array for this filtering, with array_diff ()

    "But I still have to iterate to print"

    Only if you want. Because a one-dimensional array can be perfectly printed with implode() , with HTML and everything:

    $data = array( 1,2,3,4,5,6,7,8,9,10 );
    
    $lowerThanFive = array_filter(
    
        $data,
    
        function( $current ) {
    
            return ( $current <= 5 );
        }
    );
    
    printf(
    
        "<ul>\n    <li>%s</li>\n</ul>",
    
        implode( "</li>\n    <li>", $lowerThanFive )
    );
    
    printf(
    
        "\n\n<ul>\n    <li>%s</li>\n</ul>",
    
        implode( "</li>\n    <li>", array_diff( $data, $lowerThanFive ) )
    );
    

    Note that because it is an example, I have created two distinct non-ordered lists, mainly to demonstrate that it works.

        
    12.05.2014 / 19:19
    1

    Instead of displaying inside the foreach, store these values within a string and when you finish the look print the larger $ and then the smaller $

    $numeros = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
    $maiores='';
    $menores='';
    echo '<ul>';
    foreach($numeros as $numero){
    if($numero > 5){
        $maiores.= '<li>'.$numero.'</li>';
    }else{
        $menores.= '<li>'.$numero.'</li>';
      }
    }
    echo $maiores;
    echo $menores;
    echo '</ul>';
    
        
    28.05.2014 / 18:59
    0

    A simpler way to solve this, taking into account that the important thing is to select from the highest to the lowest and to gain performance:

    $numeros = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
    rsort($numeros);
    
    foreach($numeros as $numeroSelecionado)
    {
        echo $numeroSelecionado.'<br/>';
    }
    
        
    10.05.2014 / 12:14