Reorder variables by throwing the blanks to the end

Asked

Viewed 63 times

1

I intend to play to the end of the list the variables that are null. This is part of the composition of the elements of view, are blocks that can come empty, and I want to avoid having to compare the variables and regroup. How can I redo the display order of the elements on the page by throwing the empty items to the end?

In the example below I have the variables A, B and C, in the normal case would make a foreach( $variavel_X as $linha ) and would have:

$variavel_A: nada aqui
$variavel_B: [ 'linha 1' , 'linha 2' , 'linha 3' ]
$variavel_C: [ 'linha 1' , 'linha 2' , 'linha 3' ]

What I need is to display as in the order below, where the empty variable appears last

$variavel_B: [ 'linha 1' , 'linha 2' , 'linha 3' ]
$variavel_C: [ 'linha 1' , 'linha 2' , 'linha 3' ]
$variavel_A: nada aqui

I thought of playing the variables in an array and reordering with arsort, but the function will make the order ascending(a-z) or descending(z-a), and that does not interest me much.

  • $variavel_A, B, C are positions of an array? array('variavel_A' => array('linha1','linha2','linha3'))

  • In this case they are not, but I can play in an array if necessary to resolve the issue. Suggestion?

3 answers

2

uasortSorts an array using a user-defined comparison function and keeping associations between keys and values.

See an example of how to use based on your question:

<?php

// Definição dos arrays
$arr = array();
$arr['a'] = array();
$arr['b'] = array('linha1','linha2','linha3', 'linha4');
$arr['c'] = array('linha1','linha2','linha3');
$arr['d'] = array();
$arr['e'] = array('linha1','linha2','linha3');
$arr['f'] = array('linha1','linha2','linha3');
$arr['g'] = array();
$arr['h'] = array('linha1','linha2','linha3');

// Função personalizada para ordenar os arrays
// 0 quer dizer igual, -1 joga para o início e 1 para o final.
function sortArrays($a, $b) {
    
    if(count($a) == count($b)){
    	return 0;
    }

    return (count($a) > count($b)) ? -1 : 1;
}

// Reordena os arrays
uasort($arr, 'sortArrays');

// Imprime o array ordenado
print_r($arr);

?>

Final result:

Array
(
    [b] => Array
        (
            [0] => linha1
            [1] => linha2
            [2] => linha3
            [3] => linha4
        )

    [c] => Array
        (
            [0] => linha1
            [1] => linha2
            [2] => linha3
        )

    [e] => Array
        (
            [0] => linha1
            [1] => linha2
            [2] => linha3
        )

    [f] => Array
        (
            [0] => linha1
            [1] => linha2
            [2] => linha3
        )

    [h] => Array
        (
            [0] => linha1
            [1] => linha2
            [2] => linha3
        )

    [a] => Array
        (
        )

    [d] => Array
        (
        )

    [g] => Array
        (
        )

)

  • 1

    Another aternativa would be to change to function sortArrays($a, $b) { return count($b) <=> count($a); } would do exactly the same thing, with less code.

  • @Inkeliz, yes, thanks for the tip, but just a reminder, this goes for PHP 7 onwards, versions below would not work.

2

There are many Sorting algorithms to solve your case.

But let’s go to the classic Bubble Sort

How it works:

This algorithm traverses the list of ordinable items from start to finish, checking the order of the elements two by two, and changing them if necessary. Scroll through the list until no element has been moved in the previous passage.

So, let’s assume you’re using a two-dimensional array:

$arr = array();
$arr['a'] = array();
$arr['b'] = array('linha1','linha2','linha3');
$arr['c'] = array('linha1','linha2','linha3');
$arr['d'] = array();
$arr['e'] = array('linha1','linha2','linha3');
$arr['f'] = array('linha1','linha2','linha3');
$arr['g'] = array();
$arr['h'] = array('linha1','linha2','linha3');

Creating this code below, you will be checking each item to put the empty arrays last:

function bubble_sort(&$array){

        $tam = count($array);

        reset($array);//Aponta para primeira posição

        for($i = 0; $i<$tam; $i++){
            for($j = 0; $j<($tam-1); $j++){             
                //Pega dados da posição atual
                $current_position = each($array);
                //Pega dados da proxima posição
                $next_position = each($array);
                prev($array); //Volta posição   

                if(empty($current_position['value']) &&
                   !empty($next_position['value'])){              
                    $array[$current_position['key']] = $next_position['value'];
                    $array[$next_position['key']] = $current_position['value'];                                 
                }

            }
            reset($array);//Aponta para primeira posição
        }

    }

    bubble_sort($arr);

    echo json_encode($arr);

Entree:

{"a":[],"b":["linha1","linha2","linha3"],"c":["linha1","linha2","linha3"],"d":[],"e":["linha1","linha2","linha3"],"f":["linha1","linha2","linha3"],"g":[],"h":["linha1","linha2","linha3"]}

Exit:

{"a":["line1","Linha2","line3"],"b":["line1","Linha2","line3"],"c":["line1","Linha2","line3"],"d":["line1","Linha2","line3"],"and":["line1","Linha2","line3"],"f":[],"g":[],"h":[]}

  • I was thinking of something simpler, I came up with the following: filter on each element of the array, then filter the array - I will only have indexes with values - and then combine with the old array. The result is the same, null values at the end. Take a look

  • It was a first test, I still don’t know if it’s totally accurate. But TKS for the answer.

1


Using only foreach could do:

foreach($array as $index => $valor){

    if(empty($valor)){
        unset($array[$index]);
        $array[$index] = $valor;
    }

}

This will check whether it is empty and will remove it from the array and add it to a new one, which will be included at the end of the array, so consider:

$array['a'] = [];
$array['b'] = ['linha1','linha2','linha3'];
$array['c'] = ['linha1','linha2','linha3'];
$array['d'] = null;
$array['e'] = ['linha1','linha2','linha3'];
$array['f'] = ['linha1','linha2','linha3'];
$array['g'] = '';
$array['h'] = ['linha1','linha2','linha3'];

foreach($array as $index => $valor){

    if(empty($valor)){
        unset($array[$index]);
        $array[$index] = $valor;
    }

}

Upshot:

array(8) {
  ["b"]=>
  array(3) {
    [0]=>
    string(6) "linha1"
    [1]=>
    string(6) "linha2"
    [2]=>
    string(6) "linha3"
  }
  ["c"]=>
  array(3) {
    [0]=>
    string(6) "linha1"
    [1]=>
    string(6) "linha2"
    [2]=>
    string(6) "linha3"
  }
  ["e"]=>
  array(3) {
    [0]=>
    string(6) "linha1"
    [1]=>
    string(6) "linha2"
    [2]=>
    string(6) "linha3"
  }
  ["f"]=>
  array(3) {
    [0]=>
    string(6) "linha1"
    [1]=>
    string(6) "linha2"
    [2]=>
    string(6) "linha3"
  }
  ["h"]=>
  array(3) {
    [0]=>
    string(6) "linha1"
    [1]=>
    string(6) "linha2"
    [2]=>
    string(6) "linha3"
  }
  ["a"]=>
  array(0) {
  }
  ["d"]=>
  NULL
  ["g"]=>
  string(0) ""
}

Test this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.